1、按顺序更新,比如你那两个,同时都更新id相同的,这样一般只是阻塞而已,不至于死锁。
2、使用乐观并发,比如行版本存储技术来避免。
3、改设计,这个太痛苦了。
4、合理的查询和索引,加快速度。
5、保证事务尽可能短,比如你上面,如果不是非要两个id的update都放在一起,那最好分开两个事务

解决方案 »

  1.   

    我做的一个实验,就是这种情况,两个事务,都访问同一个表的,2条数据,由于这是访问的顺序不同,导致了死锁通过DBCC Page查看在SQL Server中哪行数据被锁住了?
    http://blog.csdn.net/sqlserverdiscovery/article/details/13291629
      

  2.   


    解决和预防死锁的方法下面的方法有助于将死锁减至最少:
    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中的死锁图形事件.
      

  3.   

    如果不放在同一个事务里面是根本不会死锁的开两个窗口测试--BEGIN TRAN
    WAITFOR TIME '09:59:54';
    update [ta] set id=id+1 where id=2update [ta] set id=id+1 where id=1--COMMIT TRAN 
      

  4.   

    需看具体情况,简单讲:
    当id=1,id=2的记录在同一个数据页时,可能产生阻塞.
    当id=1,id=2的记录在不同的数据页时,可能产生死锁.
    不明白可以私信找我,给你2个测试案例.
      

  5.   

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