多用户下数据库死锁的问题

wys1978 2003-11-13 12:17:03
我们有一个应用系统,已经开发完毕,在实际使用过程发现有时会发生deadlock的情况,通过log sql语句,模拟出了这样的例子:

--Process A:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRANSACTION
UPDATE TABLE1 SET TTT='2' WHERE ID = '2'
waitfor delay '00:00:05'
UPDATE TABLE2 SET TTT='2' WHERE ID = '1'
exec sp_lock
COMMIT TRANSACTION

--Process B:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRANSACTION
UPDATE TABLE2 SET TTT='2' WHERE ID = '2'
waitfor delay '00:00:05'
UPDATE TABLE1 SET TTT='2' WHERE ID = '1'
exec sp_lock
COMMIT TRANSACTION

TABLE1 和 TABLE2 都是一样的结构:
Field: ID, Type: VARCHAR 20 (PK)
Field: TTT, Type: VARCHAR 20

开2个查询分析器,同时运行A和B,就可以重现死锁的情况。

看到的锁类型是键范围锁定,而按照SQL Server的联机文档说明在READ UNCOMMITTED的事务之下,对应主键行的更新应该是行锁定才对。

我修改PK的type到numeric,却是没有这样的问题。SQL Server难道对于不同的主键类型的锁定策略是不一样的吗?

系统已经完成了,不想修改原有的代码,能否有其他变通的方式?

谢谢!
...全文
67 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
happydreamer 2003-11-15
  • 打赏
  • 举报
回复
你现在的语句是没有死锁的

READ UNCOMMITTED
执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁


如果改成这样就会死锁了


--Process A:
BEGIN TRANSACTION
UPDATE TABLE1 SET TTT='2' WHERE ID = '2'
waitfor delay '00:00:10'
UPDATE TABLE2 SET TTT='2' WHERE ID = '1'
exec sp_lock
COMMIT TRANSACTION



--Process B:
BEGIN TRANSACTION
UPDATE TABLE2 SET TTT='2' WHERE ID = '1'
waitfor delay '00:00:10'
UPDATE TABLE1 SET TTT='2' WHERE ID = '2'
exec sp_lock
COMMIT TRANSACTION
执行B 将会提示
事务(进程 ID 60)与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。

你仔细比较一下,还有不推荐改变SQL server默认事务隔离级别
cgsun 2003-11-14
  • 打赏
  • 举报
回复
我这好象不会琐。
来这里听课
txlicenhe 2003-11-13
  • 打赏
  • 举报
回复
哈哈,不研究这个,锁就锁,管它是什么锁呢。

我也听楼下的讲课。
愉快的登山者 2003-11-13
  • 打赏
  • 举报
回复
试加WITH (ROWLOCK):

UPDATE TABLE1 WITH (ROWLOCK) SET TTT='2' WHERE ID = '2'

34,623

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧