第18/24周 乐观并发控制(Optimistic Concurrency)
大家好,欢迎回到性能调优培训。上个星期我通过讨论悲观并发模式拉开了第5个月培训的序幕。今天我们继续,讨论下乐观并发模式(Optimistic Concurrency)。
行版本(Row Versioning)
乐观并发模式自SQL Server 2005后引入,并基于行版本控制(Row Versioning)原则。行版本控制背后的想法是读操作(SELECT查询)不再需要获得共享锁(Shared Lock)。不去等待直到成功获得共享锁(Shared Lock),读操作是返回行前一个提交的版本。老的,前一个版本被存储在所谓的版本存储(Version Store)里,这个在TempDb里永驻。写操作(UPDATE,DELETE语句)明确复制老版本到版本存储,新版本中含一个指针指向versionstore里面旧行。下图诠释了这个概念。
增加这个指针的一个副作用是每个记录会增加额外的14 bytes。这会带来:
- 堆表上的转发记录(Forwarding Records)
- 聚集表上的页分裂(Page Splits)
另外,你也要按需计划和大小TempDb,因为你会引入额外的I/O,在默认配置下会带来竞争问题。现在让我们看看SQL Server提供给你的2个新的乐观隔离级别(optimistic isolation levels)。
乐观隔离级别(Optimistic Isolation Levels)
自SQL Server 2005起,关系引擎提供2个新的乐观隔离级别,它们是基于上一部分讨论过的行版本控制概念。
- 读提交快照隔离(Read Committed Snapshot Isolation (RCSI))
- 快照隔离(Snapshot Isolation (SI))
我们来详细看下这2个隔离级别。RCSI提供你基于快照语句级别的隔离。换句话说,SQL Server总会返回你在语句开始前有效的版本。它是提交读隔离级别(Read Committed Isolation Level)的乐观实现。因此使用这个隔离级别你会有不可重复读(Non-Repeatable Reads)。
ALTER DATABASE AdventureWorks2012 SET READ_COMMITTED_SNAPSHOT ON
GO -- Check if RCSI is now enabled
SELECT name,is_read_committed_snapshot_on
FROM sys.databases
WHERE database_id = DB_ID('AdventureWorks2012')
GO
RCSI的一个好处是对数据库/应用程序本身它是完全透明的:你重要在数据库上启用它,然后对于每个查询新的默认隔离级别是读提交快照隔离(Read Committed Snapshot Isolation)。因此通过对指定数据库启用RCSI,你可以克服锁和阻塞问题,即使死锁问题也很容易。下面代码显示了对于给出的数据库如何启用RCSI:
对于你SELECT查询,如果你想有重复读(Repeatable Reads)的乐观方式,你可以使用快照隔离(Snapshot Isolation (SI))隔离级别。快照隔离提供你开箱即用(out of box)的重复读,这就是说你总拿到在你事务开始前有效的行版本。遗憾的是快照隔离并不完全透明:
- 快照隔离级别必须通过会话明确请求。因此在你的程序里你需要修改代码。
- 你的查询会执行如所谓的更新冲突(Update Conflicts),SQL Server会回滚事务。因此在你的程序里你需要相应的进行处理这个情况。
下面代码向你展示了对于指定的数据库,如何启用快照隔离(Snapshot Isolation),如何请求这个新的隔离级别。
-- Enable Snapshot Isolation (SI)
ALTER DATABASE AdventureWorks2012 SET ALLOW_SNAPSHOT_ISOLATION ON
GO -- Check if SI is now enabled
SELECT name, snapshot_isolation_state, snapshot_isolation_state_desc
FROM sys.databases
WHERE database_id = DB_ID('AdventureWorks2012')
GO USE AdventureWorks2012
GO -- Setting the Isolation Level to Snapshot Isolation
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
GO
小结
今天你学习了自SQL Server 2005起支持的2个乐观隔离级别。提交读快照隔离(Read Committed Snapshot Isolation (RCSI))提供你基于语句级别的隔离,快照隔离(Snapshot Isolation (SI))提供你基于事务级别的隔离,因为2个隔离级别使在永驻在TempDb里的版本存储,对于TempDb你需要仔细计划和指定标准。
下周我会谈下SQL Server 里锁和阻塞发生的问题:锁升级(Lock Escalations)。请继续关注!
围观PPT:
第18/24周 乐观并发控制(Optimistic Concurrency)的更多相关文章
- MySQL 的乐观并发控制Optimistic concurrency control
默认情况下, MySQL的Innodb事务隔离级别是重复读 repeatable read, SELECT @@GLOBAL.tx_isolation, @@tx_isolation;REPEATAB ...
- 第17/24周 悲观并发控制(Pessimistic Concurrency)
大家好,欢迎回到性能调优培训.今天标志着第5个月培训的开始,这个月我们会谈论SQL Server里的锁.阻塞和死锁(Locking, Blocking, and Deadlocking). SQL S ...
- 第0/24周 SQL Server 性能调优培训引言
大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤浅,博而不专,到现在我才发现自己的兴趣所在,于 ...
- Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁
Optimistic concurrency control https://en.wikipedia.org/wiki/Optimistic_concurrency_control Optimist ...
- 第20/24周 死锁(Deadlocking)
大家好,欢迎回到性能调优培训.今天讨论SQL Server里的死锁(Deadlocking),第5个月的培训就结束了.当2个查询彼此等待,没有查询可以继续它的工作就会发生死锁.第一步我会概括介绍下SQ ...
- 第23/24周 临时数据库(TempDb)
在今天的性能调优培训里我们讨论下TempDb——SQL Server的公共厕所,在SQL Server里我是这样描述它的.我们的每个人都会经常使用TempDb.有些人直接使用它,有些人不直接使用它.今 ...
- Optimistic Concurrency VS. Pessimistic Concurrency Control
原创地址:http://www.cnblogs.com/jfzhu/p/4009918.html 转载请注明出处 (一)为什么需要并发控制机制 并发控制机制是为了防止多个用户同时更改同一条数据,也 ...
- Entity Framework 乐观并发控制
一.背景 我们知道,为了防止并发而出现脏读脏写的情况,可以使用Lock语句关键字,这属于悲观并发控制的一种技术,,但在分布式站点下,锁的作用几乎不存在,因为虽然锁住了A服务器的实例对象,但B服务器上的 ...
- elasticsearch 基础 —— 处理冲突及乐观并发控制
处理冲突 当我们使用 index API 更新文档 ,可以一次性读取原始文档,做我们的修改,然后重新索引 整个文档 . 最近的索引请求将获胜:无论最后哪一个文档被索引,都将被唯一存储在 Elastic ...
随机推荐
- java HashMap那点事
集合类的整体架构 比较重要的集合类图如下: 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否 否 HashSet TreeSet 是(用二 ...
- Redis 发布订阅
订阅: class Program { //版本2:使用Redis的客户端管理器(对象池) public static IRedisClientsManager redisClientManager ...
- 在Linux上用supervisor运行ASP.NET Core站点的一个坑
将一个ASP.NET Core站点在Linux服务器上以self-contained部署方式发布出来后,直接在终端上运行下面的命令,站点可以正常运行. /data/AboutUs/bin/Debug/ ...
- Java多线程12:ReentrantLock中的方法
公平锁与非公平锁 ReentrantLock有一个很大的特点,就是可以指定锁是公平锁还是非公平锁,公平锁表示线程获取锁的顺序是按照线程排队的顺序来分配的,而非公平锁就是一种获取锁的抢占机制,是随机获得 ...
- Unity3D入门之Unity3D介绍以及编辑器的使用(1)
1.Unity3D介绍 Unity3D是跨平台(IOS.Android.Windows Phone.Windows.Flash.XBOX360.PS3.Wii等)游戏引擎,可以开发2D.2.5D.3D ...
- C# socket编程实践——支持广播的简单socket服务器
在上篇博客简单理解socket写完之后我就希望写出一个websocket的服务器了,但是一路困难重重,还是从基础开始吧,先搞定C# socket编程基本知识,写一个支持广播的简单server/clie ...
- Visual Studio 2015 速递(4)——高级特性之移动开发
系列文章 Visual Studio 2015速递(1)——C#6.0新特性怎么用 Visual Studio 2015速递(2)——提升效率和质量(VS2015核心竞争力) Visual Studi ...
- IOS 多线程01-线程基础知识
大部分现代操作系统,包括IOS,都支持执行线程的概念.每个进程可以包含多个线程,他们可以同时运行.如果只有一个处理器核心,操作系统将在所有执行线程之间切换,非常类似于在所有执行线程之间切换.如果拥有多 ...
- jmap
环境: 现有一个独立运行的系统S(有独立的jre,但是没jdk),现想通过jmap导出其内存堆栈信息.于是另外安装一个jdk.可是jdk的版本跟S系统的jre不能对应上.出了很多错误. 总是报错: C ...
- Js~对数组进行分组户数
在sql里有group by,主要对数据结果集进行分组统计,而对于JS来说,有时我们也需要这种功能,例如一个数据{"dog","cat","dog&q ...