关于SQLServer数据库的READ_COMMITTED_SNAPSHOT隔离级别
默认情况下,SQL Server的事务隔离级别是READ COMMITED。刚开始我理解这个模式就是读已经提交的,那也就是说并发一个事务去更新,一个事务查询同一条数据应该是像Mysql、Oracle不会加锁直接返回数据库已经提交的数据才对。但是SQL Server不是这样的。
SQLServer中有READ_COMMITTED_SNAPSHOT,这个才不会对读加锁,直接读取提交的快照。
事务隔离级别是确保数据一致性和并发控制的重要机制。SQL Server 提供了多种事务隔离级别,其中READ_COMMITTED_SNAPSHOT(读已提交快照)是一个特别值得注意的选项,它在提高并发读取性能的同时,也带来了一些独特的特性和考量。本文将详细探讨READ_COMMITTED_SNAPSHOT的作用、优势、潜在影响及配置建议,并附上官方文档链接,以供深入学习。
什么是READ_COMMITTED_SNAPSHOT?
READ_COMMITTED_SNAPSHOT隔离级别是SQL Server中的一种事务处理模式,它改变了传统的READ_COMMITTED隔离级别下读取数据的方式。在标准的READ_COMMITTED级别,读取操作会加上锁来阻止其他事务修改正在读取的数据,这可能导致锁争用,影响并发性能。而启用READ_COMMITTED_SNAPSHOT后,读取事务不再请求共享锁,而是访问一个数据行的快照版本,这个版本是在事务开始时就已经存在的数据状态。这种方式减少了锁的使用,从而提高了并发读取的性能。
启用和禁用READ_COMMITTED以及SNAPSHOT
注意这里是全局设置,不是只针对当前事务
启用:
ALTER DATABASE 数据库名 SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE 数据库名 SET READ_COMMITTED_SNAPSHOT ON;
ALTER DATABASE 数据库名 SET MULTI_USER;
禁用,恢复到默认(READ COMMITED):
ALTER DATABASE 数据库名 SET SINGLE_USER WITH ROLLBACK IMMEDIATE; ALTER DATABASE 数据库名 SET READ_COMMITTED_SNAPSHOT OFF; ALTER DATABASE 数据库名 SET MULTI_USER;
查询当前数据库隔离级别:DBCC USEROPTIONS
主要优势
- 减少锁争用:由于不加锁读取,大大降低了并发事务之间的锁等待和阻塞,提高了系统的吞吐量。
- 非阻塞读取:即使其他事务正在修改数据,读取事务也能顺利进行,不会被阻塞。
- 简化编程模型:对于开发者来说,可以减少因锁定引发的异常处理逻辑,使得应用程序编写更加简单。
潜在影响
- tempdb使用增加:快照数据存储在
tempdb中,因此tempdb的大小和I/O负载可能会显著增加。 - 存储和内存需求上升:维护行版本会占用更多的存储空间和内存资源。
- 可能的数据不一致性:尽管名为“读已提交”,但实际读取的是事务开始时刻的数据快照,因此在高并发写入场景下,可能无法反映最新数据状态。
- 性能考量:对于写密集型应用,启用
READ_COMMITTED_SNAPSHOT可能不如预期那样提升性能,因为额外的版本管理操作会带来开销。
官方文档链接
推荐直接参考微软官方文档:
结论
READ_COMMITTED_SNAPSHOT隔离级别是提升并发读取性能的有效手段,特别是在读多写少的应用场景中。然而,它的采用需权衡利弊,特别是对tempdb的管理和监控,以及对数据一致性的理解和接受程度。在决定启用此选项之前,应充分评估系统的特定需求、资源限制和业务逻辑,以确保最佳的性能与数据完整性平衡。
另外,不推荐在代码中使用select xx,oo from table_n(nolock)这种东西,也就是不要随便使用NOLock,官方也不推荐这么使用,除非你能接受它带来的负面影响,一句话它是脏读:读未提交的数据。一个事务正在修改,还未提交,另一个事务使用nolock就能查到,并且可能把数据上送传入其他系统,但是如果那个事务最终并未提交呢?那上送的这种数据就是无头案了。【官方也不推荐这么使用】
关于SQLServer数据库的READ_COMMITTED_SNAPSHOT隔离级别的更多相关文章
- 数据库的快照隔离级别(Snapshot Isolation)
隔离级别定义事务处理数据读取操作的隔离程度,在SQL Server中,隔离级别只会影响读操作申请的共享锁(Shared Lock),而不会影响写操作申请的互斥锁(Exclusive Lock),隔离级 ...
- MySQL数据库事务各隔离级别加锁情况--read uncommitted篇(转)
本文转自https://m.imooc.com/article/details?article_id=17291,感谢作者 1.目的 1.1 合适人群 1.数据库事务特征我只是背过,并没有很深刻的理解 ...
- 转:数据库的快照隔离级别(Snapshot Isolation)
数据库的快照隔离级别(Snapshot Isolation) 隔离级别定义事务处理数据读取操作的隔离程度,在SQL Server中,隔离级别只会影响读操作申请的共享锁(Shared Lock),而 ...
- 数据库ACID、隔离级别与MVCC
首先需要明确事务的概念:一组原子性的SQL查询,如果数据库引擎能够成功的对数据库应用该组查询的全部语句,那么就执行该组语句,否则所有语句都不执行. 事务有ACID四个特性,即: 原子性:一个事务是一个 ...
- 「DB」数据库事务的隔离级别
*博客搬家:初版发布于 2017/04/10 00:37 原博客地址:https://my.oschina.net/sunqinwen/blog/875833 数据库事务的隔离级别 讲事务的隔离 ...
- Mysql数据库事务的隔离级别和锁的实现原理分析
Mysql数据库事务的隔离级别和锁的实现原理分析 找到大神了:http://blog.csdn.net/tangkund3218/article/details/51753243 InnoDB使用MV ...
- MySQL数据库的事物隔离级别
一. 查看数据库的事物隔离级别 mysql> show variables like '%isolation'; +-----------------------+--------------- ...
- Spring中事务的传播行为,7种事务的传播行为,数据库事务的隔离级别
Propagation.REQUIRED 代表当前方法支持当前的事务,且与调用者处于同一事务上下文中,回滚统一回滚(如果当前方法是被其他方法调用的时候,且调用者本身即有事务),如果没有事务,则自己新建 ...
- 设置SQLServer的行版本控制隔离级别
1.--查询数据库状态 select name,user_access,user_access_desc,snapshot_isolation_state,snapshot_isolation_sta ...
- SqlServer中的事务隔离级别、锁机制
事务 作用:用来执行一连串的动作,并且保证所有动作要么都执行.要么都不执行. 属性:原子行.一致性.隔离性.持久性 锁 作用:SqlServer使用锁来实施事务隔离属性. 阻塞 定义:如果一个事务持有 ...
随机推荐
- Redis学习篇
Redis 能用来做什么? 01 缓存 Redis 的最常用的用例是缓存,以加快网络应用的速度.在这种用例中,Redis 将经常请求的数据存储在内存中.它允许网络服务器频繁访问的数据.这就减少了数据库 ...
- java 高效递归查询树 find_in_set 处理递归树
建表语句 DROP TABLE IF EXISTS `sys_dept`; CREATE TABLE `sys_dept` ( `id` bigint(20) NOT NULL AUTO_INCREM ...
- 使用bootstrap-select 动态加载数据不显示的问题,级联数据置为空
动态加载数据 $.showLoading('数据加载中');//开启遮挡层 $.ajax({ url: "/PickoutStock/GetSendReceive", data: ...
- c++临时对象导致的生命周期问题
对象的生命周期是c++中非常重要的概念,它直接决定了你的程序是否正确以及是否存在安全问题. 今天要说的临时变量导致的生命周期问题是非常常见的,很多时候没有一定经验甚至没法识别出来.光是我自己写.rev ...
- [oeasy]python0109_tty_打字头_电传打字机_字模_点阵字库
点阵字库 回忆上次内容 上次回顾了 字符字型 的 进化过程 从 谷腾堡 活字 到 罗马正字 和 意大利斜体 罗马帝国战斗力的征服 和 基督教文化传播 使得 拉丁字符 在日耳曼语地区广泛传播 种葡萄 ...
- [oeasy]python0013_ASCII码表_英文字符编码_键盘字符
ASCII 码表 回忆上次内容 ord(c)和chr(i) 这是俩函数 这俩函数是一对,相反相成的⚖️ ord 通过 字符 找到对应的 数字 chr 通 ...
- Nginx $remote_addr和$proxy_add_x_forwarded_for变量详解
$remote_addr 代表客户端IP.注意,这里的客户端指的是直接请求Nginx的客户端,非间接请求的客户端.假设用户请求过程如下: 用户客户端--发送请求->Nginx1 --转发请求-- ...
- Django 多数据库配置与使用总结
Django 多数据库配置与使用总结 By:授客 QQ:103355122 #实践环境 Win 10 Python 3.5.4 Django-2.0.13.tar.gz 官方下载地址: https:/ ...
- mysql 忘记root密码怎么办?
忘记root可以跳过grant table来登录 1.打开命令行输入以下命令 mysqld -nt --grant-skip-tables 2.在打开一个新命令行,输入以下命令可以登录, mysql ...
- 业务场景---Token无感刷新
业务场景描述 假设用户正在填写一个复杂的表单,由于表单内容繁多,用户花费了很长时间才填完.这时,如果Token已经过期,系统会让用户重新登录,这种体验显然是非常糟糕的.为了避免这种情况,我们需要在To ...