私は次のことを考えています:
従来の行ストアテーブルと同じグローバルテンポラリテーブルで使用されるロック(読み取り用に共有され、挿入/削除用に排他的)です。
一時テーブルの場合、現在のコンテキストで「存続」するため、ブロックは発生しないと思います。そのため、データの読み取りと挿入を同時に行うことはできません。
しかし、グローバル一時テーブルの場合、多くの操作があるとしましょう。新しいデータを挿入する操作、データを削除する操作、データを読み取ろうとする操作は削除されます。
テーブルの構造が次のとおりだとします。
GroupID EntityID
1 101
1 102
1 103
2 101
2 104
3 100
同じルール はここに適用されますか?
私はこの質問に興味があり、tempdbが特別なデータベースであるか、またはデフォルトの分離「Read Committed」が適用されている別のユーザーデータベースと同じであるかを確認したいと思いました。
以下は私が実行したクエリです:
--Created two tables in tempdb, one named table and second one as gobal tempdb table
select * into tempdb.dbo.msgs from sys.messages
select * into ##msgs from sys.messages
次のウィンドウでこれらのテーブルのいくつかのレコードに対して実行された更新クエリ
begin tran
go
update dbo.msgs set language_id = 1055 where message_id = 11242
go
update ##msgs set language_id = 1055 where message_id = 11242
go
上記の両方のステートメントで、予想どおり22行が更新されました。
後で、私は2つの異なるウィンドウでこれら2つのテーブルに対してselectステートメントを実行しましたが、これまでのところ両方ともスタックしています。
最初のクエリでは画面にレコードがまったく表示されないのに対し、2番目のケースでは、8830レコードが画面に表示され、その後スタックします(理由は不明ですか?)。彼らは更新が完了するのを待っています。これは、MSSQLデータベースのデフォルトの動作で想定されていたものです。
私はsp_whoisactiveを使用して同じことを検証し、以下のようにデータベースのブロックがあることがわかりました。
詳細については、それぞれのロック情報を示します。
第一:
<Database name="tempdb">
<Objects>
<Object name="msgs" schema_name="dbo">
<Locks>
<Lock resource_type="OBJECT" request_mode="IS" request_status="GRANT" request_count="1" />
<Lock resource_type="PAGE" page_type="*" request_mode="S" request_status="WAIT" request_count="1" />
</Locks>
</Object>
</Objects>
</Database>
2番目:
<Database name="tempdb">
<Objects>
<Object name="##msgs" schema_name="dbo">
<Locks>
<Lock resource_type="OBJECT" request_mode="IX" request_status="GRANT" request_count="1" />
<Lock resource_type="PAGE" page_type="*" request_mode="UIX" request_status="GRANT" request_count="22" />
<Lock resource_type="RID" page_type="*" request_mode="X" request_status="GRANT" request_count="22" />
</Locks>
</Object>
<Object name="msgs" schema_name="dbo">
<Locks>
<Lock resource_type="OBJECT" request_mode="IX" request_status="GRANT" request_count="1" />
<Lock resource_type="PAGE" page_type="*" request_mode="UIX" request_status="GRANT" request_count="22" />
<Lock resource_type="RID" page_type="*" request_mode="X" request_status="GRANT" request_count="22" />
</Locks>
</Object>
</Objects>
</Database>
3番目:
<Database name="tempdb">
<Objects>
<Object name="##msgs" schema_name="dbo">
<Locks>
<Lock resource_type="OBJECT" request_mode="IS" request_status="GRANT" request_count="1" />
<Lock resource_type="PAGE" page_type="*" request_mode="S" request_status="WAIT" request_count="1" />
</Locks>
</Object>
</Objects>
</Database>
また、以下のコマンドを使用して、これらの各トランザクションの分離レベルをクロスチェックしました。
SELECT CASE transaction_isolation_level
WHEN 0 THEN 'Unspecified'
WHEN 1 THEN 'ReadUncommitted'
WHEN 2 THEN 'ReadCommitted'
WHEN 3 THEN 'Repeatable'
WHEN 4 THEN 'Serializable'
WHEN 5 THEN 'Snapshot' END AS TRANSACTION_ISOLATION_LEVEL
FROM sys.dm_exec_sessions
where session_id in(63,66,67)
結果:
これらすべてについて、tempdbの場合も、分離レベルは「コミットされた読み取り」として設定され、 rules は他のデータベースと同様に適用されます。
これらのクエリをMSSQL 2019バージョンで実行しました。