我在MS SQL server 2014中有一个非常简单的表SEQ_NO,表结构如下:
CREATE TABLE SEQ_NO(
KEY_CODE varchar(30) NOT NULL,
CURR_SEQ_NO numeric(38, 0) NOT NULL,
PRIMARY KEY (KEY_CODE)
)
此表只有4条记录,每条记录都包含一个序列号。我有一个程序,有许多线程使用hibernate访问此表,将序列号增加1并检索增加的序列号。
例如,线程1-10增加并从key_code_1检索序列号,线程11-20增加并从key_code_2等检索序列号。
我处理了访问相同记录但未处理访问不同记录的线程的异常的异常,因为该表是行锁定的。 (即正确处理了线程1-10之间的异常,但未处理线程1和线程11之间的异常。)
它适用于oracle 10g和hibernate3。最近,数据库升级到SQL Server 2014,hibernate升级到版本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 :(得分:0)
通过禁用锁升级并关闭页锁来解决问题:
ALTER TABLE SEQ_NO SET (LOCK_ESCALATION = DISABLE);
ALTER INDEX SEQ_NO_PK ON SEQ_NO; SET (ALLOW_PAGE_LOCKS = OFF)