加锁的主要目的是为了防止并发操作时导致的数据不一致等问题,锁分为共享锁(S)、更新锁(U)、排他锁(X),共享锁与更新只是单向兼容?传说中的单相思?

事务

事务能保证数据操作的原子性,要么内部操作都提交,要么都回退。事务内部某个地方出错时,可以回滚前面的操作,比如更新、删除等。

BEGIN TRAN 

---报错时回滚
IF @@ERROR<>0
ROLLBACK TRAN --执行完后提交
COMMIT TRAN

共享锁

共享锁允许并发事务读取一个资源,资源上存在共享锁时,任何其他事务不能修改数据,但是允许同时读取。

HoldLock 在表上保持共享锁,直到整个事务结束。

执行查询时会默认加上共享锁。

BEGIN TRAN EE
SELECT * FROM AA(HOLDLOCK)
WAITFOR DELAY '0:0:30'
COMMIT TRAN EE
BEGIN TRAN RR
SELECT * FROM AA(HOLDLOCK)
COMMIT TRAN RR

上面的例子,都在表AA上加了共享锁,运行结果表明,即使第一个事务没有执行完,第二个事务仍然可以直接查询出结果。这就说明,共享锁是可以同时存在多个的,多个事务可以同时获取同一资源的共享锁。

排他锁

XLOCK 其他事务不能读也不能修改它锁定的资源。

执行更新时会自动添加排他锁。

共享锁与排他锁不能同时存在。

BEGIN TRAN EE
SELECT * FROM AA(HOLDLOCK)
WAITFOR DELAY '0:0:30'
COMMIT TRAN EE
BEGIN TRAN RR
UPDATE AA SET TT='' WHERE DD=''
COMMIT TRAN RR

第一个事务在执行完成之前,第二个事务的更新一直没有进行,直到第一个事务完成之后,第二个事务中执行的更新操作才能进行。这就表明,共享锁与排他锁时不能同时存在的。一旦一个事务获取到了一个资源的共享锁,那么只有等到共享锁释放之后,才能被其他事务获取排他锁。

更新锁

UPDLOCK 一次只有一个事务可以获得资源的更新锁,获取了更新锁意味着获取了从共享锁到排他锁的资格。但是不会影响其他的查询,只会阻止那些试图加更新锁的操作。同一时间在同一个资源上不能有两个更新锁,同时加共享锁时允许的。

共享锁与更新锁是兼容的,允许同时在一个资源上。

排他锁与更新锁是不兼容的,不能同时加在一个资源上。

BEGIN TRAN RR
SELECT * FROM AA(UPDLOCK)
WAITFOR DELAY '0:0:30'
COMMIT TRAN RR
BEGIN TRAN EE
SELECT * FROM AA(HOLDLOCK)
COMMIT TRAN EE

以上代码测试结果表明,在资源上加了更新锁之后,还可以继续加共享锁,也就说并不影响查询。但是,看下面的例子。

BEGIN TRAN EE
SELECT * FROM AA(HOLDLOCK)
WAITFOR DELAY '0:0:30'
COMMIT TRAN EE
BEGIN TRAN RR
SELECT * FROM AA(UPDLOCK)
COMMIT TRAN RR

上面的例子是先加共享锁,然后再加更新锁,测试结果表明,在第一个事务结束之前,第二个事务并不能获取到更新锁。所以,是不是可以说更新锁与共享锁的兼容是单向的。

BEGIN TRAN EE
SELECT * FROM AA(UPDLOCK)
WAITFOR DELAY '0:0:30'
COMMIT TRAN EE
BEGIN TRAN RR
SELECT * FROM AA(UPDLOCK)
COMMIT TRAN RR

上面的测试结果表明,不能同时获取同一个资源的更新锁。

BEGIN TRAN EE
SELECT * FROM AA(UPDLOCK)
WAITFOR DELAY '0:0:30'
COMMIT TRAN EE
BEGIN TRAN RR
--SELECT * FROM AA(XLOCK)
UPDATE AA SET TT=''
COMMIT TRAN RR

上面测试表明,加了更新锁,就不能获得排他锁。

最新文章

  1. 隐式的bean发现与自动装配机制
  2. magereverse - Magento数据库表结构
  3. Bzoj3531: [Sdoi2014]旅行
  4. C# 连接 Oracle 的几种方式
  5. 12/09 Oracle练习之新建表
  6. 全局程序集GlobalAssemblyInfo.cs进行版本控制(引)
  7. redis的使用
  8. PSD 转化成 HTML
  9. JVM-ClassLoader(转)
  10. (转)IOS笔记 #pragma mark的用法
  11. 【翻译】在Ext JS 5种使用ViewControllers
  12. 编写一个闹钟和定时关机工具(MFC VS2010)
  13. JMeter请求执行次数设置
  14. www的构建技术
  15. luogu P2327 [SCOI2005]扫雷
  16. 真正“搞”懂http协议01—背景故事
  17. C/C++.全文件名全路径名分割拆分分解
  18. Android开发中,系统是如何区分不同的App的(转自csdn)
  19. cojs 二分图计数问题1-3 题解报告
  20. Netty源码分析第2章(NioEventLoop)----&gt;第3节: 初始化线程选择器

热门文章

  1. 渐进式Web应用(PWA)入门教程(下)
  2. 【bzoj4174】tty的求助 莫比乌斯反演
  3. 【二分+容斥+莫比乌斯反演】BZOJ2440 完全平方数
  4. 【毕业】-《伯恩茅斯大学毕业证书》BU一模一样原件
  5. CSS3实例分享之多重背景的实现(Multiple backgrounds)
  6. ActiveMQ详解
  7. typeof和instansof的区别
  8. SpaceSyntax【空间句法】之DepthMapX学习:第二篇 输出了什么东西 与 核心概念
  9. [翻译 EF Core in Action 2.2] 创建应用程序的数据库上下文
  10. [开源]MasterChief 快速开发辅助类库