第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 ...
随机推荐
- C#基于Socket的简单聊天室实践
序:实现一个基于Socket的简易的聊天室,实现的思路如下: 程序的结构:多个客户端+一个服务端,客户端都是向服务端发送消息,然后服务端转发给所有的客户端,这样形成一个简单的聊天室功能. 实现的细节: ...
- MySQL2:四种MySQL存储引擎
前言 数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建.查询.更新和删除数据.不同的存储引擎提供不同的存储机制.索引技巧.锁定水平等功能,使用不同的存储引擎,还可以 ...
- Zookeeper--Zookeeper是什么
Google的三篇论文影响了很多很多人,也影响了很多很多系统.这三篇论文一直是分布式领域传阅的经典.根据MapReduce,于是我们有了Hadoop:根据GFS,于是我们有了HDFS:根据BigTab ...
- java提高篇(二一)-----ArrayList
一.ArrayList概述 ArrayList是实现List接口的动态数组,所谓动态就是它的大小是可变的.实现了所有可选列表操作,并允许包括 null 在内的所有元素.除了实现 List ...
- GitHub初体验(小菜新手github用起来)
记得自己刚认识github的时候觉得他好高端,只知道好多牛人托管代码在上面,但是还觉得离我好遥远.其实不然,用起来,哇塞,真强大. 如果你现在像我当时一样茫然,那希望我的分享能帮助到你.(记录自己用起 ...
- onCreateView中加载大位图
我的一个Fragment中,加载了一个1024*1024的图片,非常卡.解决办法 1. 将图片改为512*512 2. 异步加载. final SmartImageView mizige = (Sma ...
- 利用html 5 websocket做个山寨版web聊天室(手写C#服务器)
在之前的博客中提到过看到html5 的websocket后很感兴趣,终于可以摆脱长轮询(websocket之前的实现方式可以看看Developer Works上的一篇文章,有简单提到,同时也说了web ...
- MVVM架构~Knockoutjs系列之对象与对象组合
返回目录 在面向对象的程序设计里,对象是核心,一切皆为对象,对象与对象之间的关系可以表现为继承和组合,而在Knockoutjs或者JS里,也存在着对象的概念,今天主要说一下JS里的对象及对象的组合. ...
- Java程序员的日常 —— 多进程开发IO阻塞问题
本篇仍旧是源于最近的工作,总结一下纪念那些年埋下的坑... 背景故事 需求:"使用进程方式启动另一个程序!" 开发:"OK! Runtime.getRuntime().e ...
- struts2学习笔记之九:struts2的命名空间
struts2的命名空间适用于多人开发,根据不同模块命名不同的命名空间,方便开发和管理 struts2如果没有配置命名空间,默认命名空间为"/",Struts2中Action的完整 ...