首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

两个用户同时更新一张表里的两条记录但顺序不同会不会死锁?该如何解决

2013-11-25 
两个用户同时更新一张表里的两条记录但顺序不同会不会死锁?A用户update 表 set jeje+1 where id1update

两个用户同时更新一张表里的两条记录但顺序不同会不会死锁?
A用户
update 表 set je=je+1 where id=1
update 表 set je=je+1 where id=2
B用户
update 表 set je=je+1 where id=2
update 表 set je=je+1 where id=1

当两个用户同时操作时会不会互相锁定,造成死锁?


[解决办法]
这个是用来教学死锁的典型案例之一....基本上就逃不掉死锁的可能了
[解决办法]
除非你切换了其他隔离级别
[解决办法]
1、按顺序更新,比如你那两个,同时都更新id相同的,这样一般只是阻塞而已,不至于死锁。
2、使用乐观并发,比如行版本存储技术来避免。
3、改设计,这个太痛苦了。
4、合理的查询和索引,加快速度。
5、保证事务尽可能短,比如你上面,如果不是非要两个id的update都放在一起,那最好分开两个事务
[解决办法]
按相同的順序更新即可.
[解决办法]
我做的一个实验,就是这种情况,两个事务,都访问同一个表的,2条数据,由于这是访问的顺序不同,导致了死锁

通过DBCC Page查看在SQL Server中哪行数据被锁住了?
http://blog.csdn.net/sqlserverdiscovery/article/details/13291629
[解决办法]

解决和预防死锁的方法

下面的方法有助于将死锁减至最少:
1.按同一顺序访问对象。

2.避免失误中的用户交互。

3.保持事务简短并处于一个批处理中。

4.使用较低的隔离级别,如:使用nolock参数,让SELECT语句不要申请S锁。

5.调整索引,以调整执行计划,减少锁的申请数目,从而消除死锁。

6. 升级锁的粒度,将死锁转化成一个阻塞问题。  

死锁问题的定位
死锁检测是由锁监视器这个系统线程执行的,会定期搜索SQL Server里的所有任务,默认时间间隔为5秒.
检测到死锁后,数据库引擎通过选择其中一个线程作为死锁牺牲品来结束死锁,并回滚死锁牺牲品的事务,会释放事务持有的所有锁,
将1205错误返回到应用程序,这将使其他线程的事务解锁,并继续运行.
默认情况下,数据库引擎选择运行回滚开销最小的事务的会话作为死锁牺牲品.

为了查看死锁信息,数据库引擎提供了监视工具:
1.两个跟踪标志1204和1222。
  跟踪标志1204和1222会向SQL Server错误日志返回捕获的信息。
  跟踪标志1204会报告由死锁所涉及的每个节点设置格式的死锁信息,它是SQL Server 2005之前版本就有的功能。
  跟踪标志1222是SQL Server 2005才开始有的新功能,会设置死锁的信息格式,顺序为先按进程,然后按资源,
  1222的结果不但基本包含了1204的所有信息,还包含了许多1204没有的信息,
  所以在SQL Server 2005以后,可以直接使用1222来跟踪死锁: DBCC TRACEON(1222,-1).
  
2.SQL ServerProfiler中的死锁图形事件.


[解决办法]
如果不放在同一个事务里面是根本不会死锁的

开两个窗口测试

--BEGIN TRAN
WAITFOR TIME '09:59:54';
update [ta] set id=id+1 where id=2

update [ta] set id=id+1 where id=1

--COMMIT TRAN 
[解决办法]

引用:
A用户
update 表 set je=je+1 where id=1
update 表 set je=je+1 where id=2
B用户
update 表 set je=je+1 where id=2
update 表 set je=je+1 where id=1

当两个用户同时操作时会不会互相锁定,造成死锁?

需看具体情况,简单讲:
当id=1,id=2的记录在同一个数据页时,可能产生阻塞.
当id=1,id=2的记录在不同的数据页时,可能产生死锁.
不明白可以私信找我,给你2个测试案例.
[解决办法]
引用:
那么多用户同时更新一张表的多条记录,怎样才能避免死锁呢?

同个用户的多个更新,不加事务(transaction).

热点排行