2013-12-03 7 views
6

私は、完全なテーブルが行ではなくロックされるのはなぜですか?

create table temp 
(
    id int, 
    name varchar(10) 
) 
insert into temp values(1,'a'); 

をこのSQLを実行したが、その後私は、細かい

select 1 from temp where id = 1 

すべてを実行します。その後、私は

select 1 from temp where id = 1 

しかし、何も返されません。このとき、実行

それから私は、コミットされていない挿入を実行

SET NOCOUNT ON; 
    DECLARE @TranCount INT; 
    SET @TranCount = @@TRANCOUNT; 



     IF @TranCount = 0 
      BEGIN TRANSACTION 
     ELSE 
      SAVE TRANSACTION Insertorupdatedevicecatalog; 

insert into temp values(2,'b') 

。 2行目の代わりに完全なテーブルをロックするのはなぜですか?

+1

テーブルがヒープ(通常のような一意のCIはありません)であるという事実は、ここで予期しないロックを引き起こします。この問題は、ID上に一意のCIを作成することで解決します。 – usr

+0

私のローカルシステムでコードを実行しましたが、それを再現することはできません。 2番目の 'SELECT'は期待通りに1を返します。 – SchmitzIT

+0

@SchmitzIT、私はこれを新しいデータベース、新しいインストールと新しいテーブル – user960567

答えて

6

SQL Serverはテーブル全体をロックしていません。私は、単一の行IDが書き込みトランザクションによってロックされていることがわかります。

索引がないため、読者は表全体をスキャンする必要があります。

enter image description here

これは、それが挿入された行上にXロックによってブロックされることを意味します。基本的には、読者は他のトランザクションがこの行を実際にコミットするかロールバックするかを決定するのを待ちます。

enter image description here セッション51にid2が挿入されました。セッション54はブロックされたセレクトです。ここではページロックやテーブルロックはありません(ここで重要ではないインテントロックは別です)。

テーブルがヒープ(通常のような一意のCIはありません)であるという事実は、ここで予期しないロックを引き起こします。この問題は、ID上に一意のCIを作成することで解決します。

+0

上記の行を返すクエリを記述できますか? – user960567

+0

Session_idに属するSQL文を書くといいでしょう – user960567

+0

@ user960567これはもっと大きなスクリプトコレクションの一部です。これは独立したクエリではなく、他のユーティリティのページやページに依存します。 sys.dm_tran_locks(http://technet.microsoft.com/en-us/library/ms190345.aspx)から選択してください。 – usr

2

私の推測では、おそらくテーブル自体がロックされていない可能性があります。 SQL Serverは、新しい行を挿入する場所を知るために、挿入される値の周りの行の範囲をロックする必要があります(読み込みを禁止する書き込みロック)。テーブルには行がほとんどないので、テーブルがロックされているように見えます。より多くの行を追加すると、単一の行を挿入するときにこの動作が表示されません。

ところで、テーブルにはプライマリキーまたはクラスタ化インデックスが必要です。これにより、将来的に行を追加する際に役立ちます。それ以外の場合は、スキャンを実行することになります。これにより、更新(およびおそらく挿入)にかかる時間が長くなります。

+0

私はこれを新しいデータベース、新しいインストールと新しいテーブルでテストしています。あなた自身でこれをテストすることができます – user960567

+0

参考までに、私はこれをアップデートでテストしました。 UPDATEと同じ結果になります。 – user960567

+0

うん、更新は、テーブルの行数が少ないので、ほぼ同じように動作します。もちろん、挿入や更新はわずかなMSを必要とするだけなので、ロックは長くは生きられず、ユーザーは気付かないでしょう。 –

関連する問題