zoukankan      html  css  js  c++  java
  • 【SqlServer】SqlServer中的更新锁(UPDLOCK)

    UPDLOCK.UPDLOCK 的优点是允许您读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没有被更改。当我们用UPDLOCK来读取记录时可以对取到的记录加上更新锁,从而加上锁的记录在其它的线程中是不能更改的只能等本线程的事务结束后才能更改.
    测试:
    在另一个查询里:

    BEGIN TRANSACTION
    SELECT * FROM myTable WITH (UPDLOCK) WHERE Id in (1,2,3)
    waitfor delay '00:00:10'
    update myTable set [Name]='ZZ' where Id in (1,2,3)
    commit TRANSACTION

    在另一个查询里:
    SELECT * FROM myTable WHERE Id in (1,2,3)

    可以马上查询到数据。
    但如果要更新数据,必须等其他更新锁释放后才能执行。

    update myTable set [Name]='ZZ' where Id in (1,2,3)

    这就说明,有时候需要控制某条记录在我读取后就不许再进行更新,那么我就可以将所有要处理当前记录的查询都加上更新锁,以防止查询后被其它事务修改.将事务的影响降低到最小

    如果不使用这个锁的话,在项目中很有可能出现“事务(进程 ID )与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行”错误。
    例如:
    表现二:
        用户A读一条纪录,然后修改该条纪录
        这是用户B修改该条纪录
        这里用户A的事务里锁的性质由共享锁企图上升到独占锁(for update),而用户B里的独占锁由于A有共享锁存在所以必须等A释放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。
        这种死锁比较隐蔽,但其实在稍大点的项目中经常发生。
    解决方法:
        让用户A的事务(即先读后写类型的操作),在select 时就是用Update lock
        语法如下:
        select * from table1 with(updlock) where ....

  • 相关阅读:
    自学Zabbix3.6.4-触发器triggers dependencies依赖关系
    自学Zabbix3.6.3-触发器triggers expression表达式
    TSLint提示错误
    angular4.0 配置打包路径以及资源文件404问题
    angular4.0配置本机IP访问项目
    angular4.0如何引入外部插件2:declare方案
    angular4.0如何引入外部插件1:import方案
    angular4.0中form表单双向数据绑定正确姿势
    angular4.0单个标签不能同时使用ngFor和ngIf
    angular4.0使用JSONP数据请求
  • 原文地址:https://www.cnblogs.com/HDK2016/p/9555496.html
Copyright © 2011-2022 走看看