其实这一篇呢与解决我项目中遇到的问题也是必不可少的。上一篇讲到了各种锁之间的兼容性,里面有一项就是共享锁会引起死锁,如何避免呢,将我们的查询都设置中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死锁-锁与事务级别的更多相关文章

  1. [翻译]:SQL死锁-锁的类型

    很久没有写博客了,这里面的原因有很多.最近的一个项目由于客户明确提出要做下性能压力测试,使用的工具就是VS自带的压力测试工具.以前其它项目做压力测试后反馈的其中一个重要问题就是数据库的死锁.没想到我们 ...

  2. [翻译]:SQL死锁-死锁排除

    As we already saw, the reasons why we have blocking issues and deadlocks in the system are pretty mu ...

  3. sql server 锁与事务拨云见日(中)

    一.事务的概述 上一章节里,重点讲到了锁,以及锁与事务的关系.离上篇发布时间好几天了,每天利用一点空闲时间还真是要坚持.听<明朝那些事儿>中讲到"人与人最小的差距是聪明,人与人最 ...

  4. sql server 锁与事务拨云见日(上)

    一.概述 讲到sql server锁管理时,感觉它是一个大话题,因为它不但重要而且涉及的知识点很多,重点在于要掌握高并发要先要掌握锁与事务,涉及的知识点多它包括各式各样的锁,锁的组合,锁的排斥,锁延伸 ...

  5. sql server 锁与事务拨云见日(下)

    在锁与事务系列里已经写完了上篇中篇,这次写完下篇.这个系列俺自认为是有条不紊的进行,但感觉锁与事务还是有多很细节没有讲到,温故而知新可以为师矣,也算是一次自我提高总结吧,也谢谢大伙的支持.在上一篇的末 ...

  6. [翻译]:SQL死锁-阻塞

    一般情况下死锁不是一步到位的,它必须满足特定的条件,然后形成资源的循环依赖才会产生死锁,死锁之前一定会出现阻塞,由阻塞升级才有可能出现死锁,所以我们有必要了解系统中都有哪些已经被阻塞的锁. 我在解决共 ...

  7. [翻译]:SQL死锁-为什么会出现死锁

    下面这篇对理解死锁非常重要,首先死锁是如何产生的我们要清楚. We already know why blocking occurs in the system and howto detect an ...

  8. [翻译]:SQL死锁-阻塞探测

    到了这篇,才是真正动手解决问题的时候,有了死锁之后就要分析死锁的原因,具体就是需要定位到具体的SQL语句上.那么如何发现产生死锁的问题本质呢?下面这篇讲的非常细了,还提到了不少实用的SQL,但对我个人 ...

  9. SQL死锁知识及解决办法

    [翻译]:SQL死锁-死锁排除 min.jiang 2014-03-18 00:23 阅读:874 评论:1     项目中死锁的解决经历 min.jiang 2014-03-17 01:09 阅读: ...

随机推荐

  1. 让IE8支持HTML5及canvas功能!

    微软出的IE9支持HTML5,但因为不支持XP系统,暂时我还用不了. 即使能用,现阶段如果开发HTML5页面,并考虑到兼容性问题的话,恐怕也得让自己的界面支持IE6-8吧. 首先,需要让IE支持HTM ...

  2. Mvc 拼接Html 导出 Excel(服务器不用安装呦!支持2007以上版本)

    新公司,新接触,老方法,更实用. 之前接触过Webform,winfrom 的导出Excel方法 ,优点:省事.缺点:服务器必须安装Office 这几天做项目 和 大牛学习了一下 新的方法,自己加以总 ...

  3. MMO之禅(二)职业精神

    MMO之禅(二)职业精神 --心态 目标 信仰 Zephyr 201304 继续上篇,继续讲什么?打了很多腹稿点滴,从引擎架构,到上层数据.逻辑模块规划,想了很多,临起笔,却总发觉四顾心茫然,乱不可言 ...

  4. java之容器

    先来一张容器的API框架图,我们在java中所学的所有知识,都是根据下面这张图来学习的.... 容器API: 1.Collection接口------定义了存储一组对象的方法,其子接口Set和List ...

  5. yii2 [行为] behaviors 拦截器

    yii2 拦截器 在控制器中可以自定义对action的拦截器,拦截器需要继承 \yii\base\ActionFilter 参考代码: class BaseUserAuthorizeFilter ex ...

  6. 自定义组件之MoreListView

    前言 本文针对自定义组件进行一些分析.还是那句老话“授之于鱼不如授之以渔”.今天要讲的是一个自定义的可以分页的ListView. 网上都讲了些ListView分页的方法,那么为什么我在这里还需要自己写 ...

  7. gulpfile.js 合并压缩 requirejs 的配置文件

    var gulp = require("gulp"); // var babel = require("gulp-babel"); // 用于ES6转化ES5 ...

  8. HTML5[3]:中文换行

    保证中文每行第一个字,不会出现标点符号 p { white-space: pre-wrap; }

  9. udp穿透简单讲解和实现(Java)

    在上一小节中了解到了通过浏览器自带的Webrtc功能来实现P2P视频聊天.在HTML5还没有普及和制定Webrtc标准的前提下,如果要在手机里进行视频实时对话等包括其他功能的话,还是要自己实现,还比较 ...

  10. maven -- 问题解决(一)解决eclipse中maven项目出现的问题

    配置项目时出现的错误: error: Cannot change version of project facet Dynamic Web Module to 2.5. error: One or m ...