2016-08-10 14 views
1

私はMS SQLサーバー2014年に非常に単純なテーブルSEQ_NOを持って、テーブルの構造は以下の通りである:マルチスレッドのMS SQL死んロック

CREATE TABLE SEQ_NO(
     KEY_CODE varchar(30) NOT NULL, 
     CURR_SEQ_NO numeric(38, 0) NOT NULL, 
     PRIMARY KEY (KEY_CODE) 
     ) 

この表には4つだけレコードを持って、それらのそれぞれは、シーケンスが含まれています数。私は、シーケンス番号を1つ増やして、増加したシーケンス番号を取得するために、多くのスレッドがこのテーブルにアクセスしてhibernateを持つプログラムを持っています。

例えば、スレッド1-10増加し、Iが同じレコードにアクセスするスレッドの例外を扱うが、

をkey_code_1スレッド11-20増加からシーケンス番号を取得し、key_code_2等からシーケンス番号を取得しますテーブルが行ロックされているため、異なるレコードにアクセスするスレッドの例外を処理しません。 (すなわち、スレッド間の例外1-10は適切に処理されるが、スレッド1とスレッド11との間の例外は処理されない)。

これは、Oracle 10gとhibernate3で正常に動作します。最近、データベースはSQL Server 2014にアップグレードされ、休止状態はバージョン4にアップグレードされ、プログラムは機能しません。スレッド1とスレッド11が、テーブルの異なる行にアクセスしている場合でも、デッドロックになることがあります。なぜこのようなことが起きているのか、この問題を解決する方法がわかりません。

私はテーブルを確認するには、次のスクリプトを使用していたが、行ロックです:

Query1 to lock one row: 
begin tran T1; 
update SEQ_NO set CURR_SEQ_NO = CURR_SEQ_NO+1 where KEY_CODE = 'KEY_CODE_1'; 
select CURR_SEQ_NO from SEQ_NO where KEY_CODE = 'KEY_CODE_1'; 

Query2 to check another row: 
update SEQ_NO set CURR_SEQ_NO = CURR_SEQ_NO+1 where KEY_CODE = 'KEY_CODE_2'; 
select CURR_SEQ_NO from SEQ_NO where KEY_CODE = 'KEY_CODE_2'; 

私は第二のクエリのシーケンス番号を取得することができています。問題は、ロックのエスカレーションを無効にして、ページロックをオフにすることによって解決される

+0

こんにちは、デッドロック・イベントは通常、SQL Serverによって記録されます。 MS SQL Management Studioを使って見ることができます。すべてのイベントにはデッドロックSQLクエリ、犠牲者、ロックされたリソースなどの詳細情報が含まれており、グラフィカルに視覚化することもできます。管理=>拡張イベント=>セッション=> system_health => package0.eventfileに移動し、名前が 'xml_deadlock_report'のイベントを探します。いくつかのデッドロックのXMLデータを投稿できますか(XML値にカーソルを移動し、新しいタブでXMLデータ全体を開くにはダブルクリックしてください)? – Plaz

答えて

0

ALTER TABLE SEQ_NO SET (LOCK_ESCALATION = DISABLE); 
ALTER INDEX SEQ_NO_PK ON SEQ_NO; SET (ALLOW_PAGE_LOCKS = OFF) 
関連する問題