Open4

トランザクション張っている途中でエラーが起きた時の動き

白湯白湯

下記のクエリを流すと、fugaテーブルへのインサートでエラーが起き、それ以降のクエリは実行されない。
そのため、ROLLBACKも効かない。(テーブルはロックされたままとなる)

トランザクションは張られたままなので、エラー原因を直してあげると最後まで実行される。


BEGIN TRANSACTION;

INSERT INTO hoge(id, name) VALUES (1, '名前 1');

-- 存在しないテーブルにデータを入れようとする
INSERT INTO fuga(id, name) VALUES (1, 'ふが 1');

INSERT INTO hoge(id, name) VALUES (2, '名前 2');

ROLLBACK;
白湯白湯

上記のトランザクション中にSELECTできないのは、 S LOCK で取得しようとしているから。(INSERTのロックは X LOCK)

NOLOCK なら取得できるけど、未コミットのデータが取れるっぽいので必ずしも NOLOCK がいいわけではなさそう。

白湯白湯

ロック状態取得クエリ(SQL Server)

SELECT
  resource_type AS type,
  resource_associated_entity_id as entity_id,
  (
    CASE
      WHEN resource_type = 'OBJECT' THEN OBJECT_NAME(resource_associated_entity_id)
      ELSE (
        SELECT
          OBJECT_NAME(OBJECT_ID)
        FROM
          sys.partitions
        WHERE
          hobt_id = resource_associated_entity_id
      )
    END
  ) AS object_name,
  request_mode,
  request_type,
  request_status,
  request_session_id AS Session_id,
  (
    SELECT
      hostname
    FROM
      sys.sysprocesses
    WHERE
      spid = request_session_id
  ) AS ProcessName
FROM
  sys.dm_tran_locks
WHERE
  resource_type <> 'DATABASE'
ORDER BY
  request_session_id