[翻译]:SQL死锁-锁与事务级别
其实这一篇呢与解决我项目中遇到的问题也是必不可少的。上一篇讲到了各种锁之间的兼容性,里面有一项就是共享锁会引起死锁,如何避免呢,将我们的查询都设置中read uncommitted是否可行呢?其结果显示,当我们当所有的查询都设置成read uncommitted后,后面共享锁死锁基本消除了,看来还是管用的。好了下面接着翻译:
Last time we discussed a few major lock types that SQL Server uses. Shared(S), Exclusive(X) and Update(U). Today I’d like to talk about transaction isolation levels and how they affect locking behavior. But first, let’s start with the question: “What is transaction?”
上一次我们讨论了一些主要的SQL SERVER锁类型:共享锁(S),排它锁(X),以及更新锁(U)。今天我们来讲事务级别是如何影响锁的行为的。但在这之前,我们需要从一个问题开始:“什么是事务”?
Transaction is complete unit of work. Assuming you transfer money from checking account to saving, system should deduct money from the checking and add it to the saving accounts at once. Even if those are 2 independent operations, you don’t want it to “stop at the middle”, well at least in the case if bank deducts it from the checking first If you don’t want to take that risk, you want them to work as one single action.
事务是一个完整的单元工作模式。假如你从支票帐户中将钱转移到储蓄卡中,银行系统首先会从你的支票帐户中扣钱,然后再往你的储蓄卡中存钱。即使这是两个相互独立的操作,你也不想让其在中间的某一步停止,至少不能停止在银行将你的钱从支票帐户中扣除之后 。如果你不冒这个风险,那么你希望这两步操作最好是一步操作来完成。
There is useful acronym – ACID – that describes requirements to transaction:
这里有一个非常有用的编写-ACID,它将描述事务的需求:
- (A) – Atomicity or “all or nothing”. Either all changes are saved or nothing changed.
(A)-它代表所有或者是无,要么全部保存要么不保存任何数据
- (C) – Consistency. Data remains in consistent stage all the time
(C)-数据每时每刻要保持一致性
- (I) – Isolation. Other sessions don’t see the changes until transaction is completed. Well, this is not always true and depend on the implementation. We will talk about it in a few minutes
(I)-数据隔离,其它的会话看不到事务未提交的数据。这句并不总是正确的,有时依赖于系统的实现,我们后续会讲到。
- (D) – Durability. Transaction should survive and recover from the system failures
(D)-数据可以回滚,当事务执行出现异常的情况下
There are a few common myths about transactions in SQL Server. Such as:
下面是一些公共的关于事务的错误观点,例如:
- There are no transactions if you call insert/update/delete statements without begin tran/commit statements. Not true. In such case SQL Server starts implicit transaction for every statement. It’s not only violate consistency rules in a lot of cases, it’s also extremely expensive. Try to run 1,000,000 insert statements within explicit transaction and without it and notice the difference in execution time and log file size.
当我们直接写insert/update/delete这句语句时,如果没有显示的写begin tran/commit 这类语句就不存在事务。这是不正确的,实际上SQL SERVER 会隐式的为每次SQL操作都加了事务。这不光违反了数据一致性规则且往往造成的后果是非常昂贵的。可以去尝试往一个表中插入1000000条数据,第一种显示的加上事务语句,第二种不加事务语句,执行之后对比下执行的时间以及日志大小的不同。
- There is no transactions for select statements. Not true. SQL Server uses (lighter) transactions with select statements.
当执行select语句时没有事务。这是不正确的,SQL SERVER会使用轻量级的事务。
- There is no transactions when you have (NOLOCK) hint. Not true. (NOLOCK) hint downgrades the reader to read uncommitted isolation level but transactions are still in play.
当们们在select语句后面加了nolock后,就没有事务了。这也是不正确的。nolock只是降低了事务必有隔离级别为read uncommitted而已并不是没有事务。
Each transaction starts in specific transaction isolation level. There are 4 “pessimistic” isolation levels: Read uncommitted, read committed, repeatable read and serializable and 2 “optimisitic” isolation levels: Snapshot and read committed snapshot. With pessimistic isolation levels writers always block writers and typically block readers (with exception of read uncommitted isolation level). With optimistic isolation level writers don’t block readers and in snapshot isolation level does not block writers (there will be the conflict if 2 sessions are updating the same row). We will talk about optimistic isolation levels later.
每个事务都在指定的事务级别中,这里有四种悲观事务必有隔离级别:Read uncommitted (允许脏读),read committed(不允许脏读),repeatable(可重复读),serialzable以及两种经过优化后的事务级别:Snapshot 以及read committed snapshot。
注:这里事务隔离级别比较多,我理解不也太多,就省略掉了。我们比较常见的就是前面的两种,允许脏读以及不允许脏读的情况。至于后面的有关镜像相关的内容这里我不做多的翻译。
Regardless of isolation level, exclusive lock (data modification) always held till end of transaction. The difference in behavior is how SQL Server handles shared locks. See the table below:
排它锁不管事务级别,它总是占用锁到整个事务结束:
So, as you can see, in read uncommitted mode, shared locks are not acquired – as result, readers (select) statement can read data modified by other uncommitted transactions even when those rows held (X) locks. As result any side effects possible. Obviously it affects (S) lock behavior only. Writers still block each other.
所以,就像你看到的,如果在允许脏读的模式下,是不需要申请共享锁的,可以读取到其实事务还未完全提交的数据,即使这些数据已经被加上了排它锁。但这只影响共享锁,对于写的会话仍然会存在相互阻塞甚至死锁的情况。
In any other isolation level (S) locks are acquired and session is blocked when it tries to read uncommitted row with (X) lock. In read committed mode (S) locks are acquired and released immediately. In Repeatable read mode, (S) locks are acquired and held till end of transaction. So it prevents other session to modify data once read. Serializable isolation level works similarly to repeatable read with exception that locks are acquired on the range of the rows. It prevents other session to insert other data in-between once data is read.
共享锁可以任意事务隔离级别中发生,当它尝试去读取其它事务未提交的数据(行上加了排它锁)时就是会阻塞。在Read committed 模式下,共享锁的申请以及释放都是非常迅速的。在Repeatable read模式下,共享锁被申请后一直占用到事务结束,它保证其它会话不编辑其已经读取到的数据。Serializable 模式的工作方式和Repeatable非常相似,但它会锁定一定范围的数据,访问其它会话插入数据。
注:这块还没理解到位,后续有时间再补充下。
You can control that locking behavior with “set transaction isolation level” statement – if you want to do it in transaction/statement scope or on the table level with table hints. So it’s possible to have the statement like that:
在你的事务中或者是表级间的查询你可以通过设置事务隔离级别来控制锁行为,就像下面的查询语句:
So you access Table1 in read uncommitted isolation level and Table2 in serializable isolation level.
这条语句的作用就是你可以对Table1读取其它事务未提交的数据,以serializable隔离级别读取Table2的数据。
It’s extremely easy to understand the difference between transaction isolation levels behavior and side effects when you keep locking in mind. Just remember (S) locks behavior and you’re all set.
这将非常容易理解事务隔离级别行为之间的差别以及它们的副作用,你只需要记住共享锁以及你所有的设置。
Next time we will talk why do we have blocking in the system and what should we do to reduce it.
下一次我们将会讲到为什么我们的系统中会存在阻塞以及我们如何做才能减少阻塞的发生
[翻译]:SQL死锁-锁与事务级别的更多相关文章
- [翻译]:SQL死锁-锁的类型
很久没有写博客了,这里面的原因有很多.最近的一个项目由于客户明确提出要做下性能压力测试,使用的工具就是VS自带的压力测试工具.以前其它项目做压力测试后反馈的其中一个重要问题就是数据库的死锁.没想到我们 ...
- [翻译]:SQL死锁-死锁排除
As we already saw, the reasons why we have blocking issues and deadlocks in the system are pretty mu ...
- sql server 锁与事务拨云见日(中)
一.事务的概述 上一章节里,重点讲到了锁,以及锁与事务的关系.离上篇发布时间好几天了,每天利用一点空闲时间还真是要坚持.听<明朝那些事儿>中讲到"人与人最小的差距是聪明,人与人最 ...
- sql server 锁与事务拨云见日(上)
一.概述 讲到sql server锁管理时,感觉它是一个大话题,因为它不但重要而且涉及的知识点很多,重点在于要掌握高并发要先要掌握锁与事务,涉及的知识点多它包括各式各样的锁,锁的组合,锁的排斥,锁延伸 ...
- sql server 锁与事务拨云见日(下)
在锁与事务系列里已经写完了上篇中篇,这次写完下篇.这个系列俺自认为是有条不紊的进行,但感觉锁与事务还是有多很细节没有讲到,温故而知新可以为师矣,也算是一次自我提高总结吧,也谢谢大伙的支持.在上一篇的末 ...
- [翻译]:SQL死锁-阻塞
一般情况下死锁不是一步到位的,它必须满足特定的条件,然后形成资源的循环依赖才会产生死锁,死锁之前一定会出现阻塞,由阻塞升级才有可能出现死锁,所以我们有必要了解系统中都有哪些已经被阻塞的锁. 我在解决共 ...
- [翻译]:SQL死锁-为什么会出现死锁
下面这篇对理解死锁非常重要,首先死锁是如何产生的我们要清楚. We already know why blocking occurs in the system and howto detect an ...
- [翻译]:SQL死锁-阻塞探测
到了这篇,才是真正动手解决问题的时候,有了死锁之后就要分析死锁的原因,具体就是需要定位到具体的SQL语句上.那么如何发现产生死锁的问题本质呢?下面这篇讲的非常细了,还提到了不少实用的SQL,但对我个人 ...
- SQL死锁知识及解决办法
[翻译]:SQL死锁-死锁排除 min.jiang 2014-03-18 00:23 阅读:874 评论:1 项目中死锁的解决经历 min.jiang 2014-03-17 01:09 阅读: ...
随机推荐
- windows 程序设计自学:添加图标资源
#include <windows.h> #include "resource.h" LRESULT CALLBACK MyWndProc( HWND hwnd, // ...
- JRE 1.8.0_65/66 Certified with Oracle E-Business Suite
Java Runtime Environment 1.8.0_65 (a.k.a. JRE 8u65-b17) and JRE 1.8.0_66 (8u66-b17) and later update ...
- [原]Android打包之Gradle打包
最近尝试了一下Android的Gradle打包,发现确实比Ant打包会方便很多,特此记录下来. 注:android的gradle现在插件的版本已经是0.14.3了,对于一些老的方法和api,有一些已经 ...
- 实现无锁的栈与队列(5):Hazard Pointer
两年多以前随手写了点与 lock free 相关的笔记:1,2,3,4,质量都不是很高其实(读者见谅),但两年来陆陆续续竟也有些阅读量了(可见剑走偏锋的技巧是多容易吸引眼球).笔记当中在解决内存释放和 ...
- Android debug时一直处于waiting for debugger解决办法
问题:android 调试卡在:Waiting for Debugger - Application XXX is waiting for the debugger to Attach" 解 ...
- 欲善其事必先利其器---Xcode插件
Xcode所有的插件都安装在目录~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/ Alcatraz (用于管理xcode插件 ...
- css的两种引用方式 link和@import
学习web开发的最大乐趣就是不断的发现自己以前不曾见过的东西,这些东西对于我来说是那么的新鲜有趣. 比如说今天偶尔研究别人的网站,就发现了有趣的东东. 当点开此网页的css时(这个css文件命名方式就 ...
- 封装系统自带的Debug
Unity3d的Debug.Log函数用于打印日志,一般项目中都会对其作如下两件事情: (1)希望有一个总的开关来控制整个游戏中日志的打印与否: (2)有的系统会将Log封一层并添加统一的标记,比如S ...
- Python - 利用pip管理包
下载与安装setuptools和pip https://pypi.python.org/packages/source/s/setuptoolshttps://pypi.python.org/pypi ...
- 初用DataGrip,连接后看不到自己创建的数据库的问题
1.首先,成功连接数据库服务 2.可以看到默认连接到名为"larins_qr_db"的数据库 3.这时,我想看其它的数据库怎么办? 4.OK,想要的出现了!