2011-02-04 12 views
1

私はそれを実行している間、更新されている特定の行を防ぐためにROWLOCKを使用しようとしているが、問題はこれを実行している間、私は全くのテーブルを使用することができないということです。ROWLOCKロックエスカレーション

set transaction isolation level repeatable read; 
go 

    begin try 
     begin transaction; 

     insert into tableB with(rowlock) 
      select * from tableA with(rowlock) where status = 1 

     commit transaction; 
    end try 
    begin catch 
     if xact_state() <> 0 
     begin 
      rollback transaction; 
     end 
    end catch; 

私は走りましたこのトランザクションが実行されている間に両方のテーブルの挿入が行われ、コミットを待っていました。特定の行を読み書きするためにロックするのに、テーブルを使用可能にするにはどうすればよいですか?

レコードの場合、selectは数万のレコードを生成します。表には主キーがクラスター化されており、状況列には索引があります。

+2

ロックエスカレーションに関するこのMSDNの記事は、http://msdn.microsoft.com/en-us/library/ms184286.aspxを参照してください。具体的には、「データベースエンジンは行またはキー範囲のロックをページロックにエスカレートせず、直接テーブルロックにエスカレートしません」とロックエスカレーションが発生するしきい値(〜5000ロック)があるという事実 – AdaTheDev

+0

'これが実行されている間、あなたはTableAに挿入していますか? –

答えて

1

特定の行を個別にロックしようとは勧めません。私はあなたが解決しようとしているよりも多くの問題にぶつかると思います。説明したロックの問題にぶつかっている理由は、挿入されている行数が表の行数と比較されるためです。 SQL Serverの裁量で、ロックは行ロックからページロック、テーブルロックにエスカレートします。

ロッキングの量を減らすために、ずっと小さなトランザクションバッチで行を挿入するほうがはるかに良いと思います。言い換えれば、一度に100行を挿入しようとすると、トランザクションでロック可能なパフォーマンスが得られるかどうかを確認できます。

+1

「あなたのテーブルの行数と比べて」アスペクトに関する議論はありますか?私はそれがAdaのリンクごとにテーブルのサイズに関係なく、フラットな5,000の制限だと思った。 –

+0

私はそれを試みました。私の魔法の数は1バッチあたり約500でした。 500 select-> insertは10秒と言いますが、テーブルは10秒間に500レコード以上挿入されますので、私はそれを決して空にできません:) – dstr

関連する問題