高并发与锁(二)

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介:

上文我们介绍了高并发状态下会产生的一些数据冲突和锁的一些基本分类,这次我们继续讨论。

    如何添加乐观锁? 在高并发情况下,如何高效、健康地给select 语句加上行锁?SQL Server是如何控制并发冲突的?

 

    1、添加乐观锁

 

    在J2EE中,Hirbernate提供了悲观所和乐观锁,但悲观锁的使用同样也限制了读取的并发性,因此很少使用,二使用最多的是添加乐观锁,在记录中添加版本version或者时间戳字段,这样做并不影响读取,只是按照版本控制的思维来限制低版本记录修改操作。
    对于以上两种方式,hibernate自带实现方式:在使用乐观锁的字段前加annotation: @Version, Hibernate在更新时自动校验该字段。
    那么有人要问,低版本记录有新的数据,怎么才能更新?
    其实也很简单:开启事务->更新记录前,读取一次最新的数据->提交->回滚或者提交事务。
    又该如何保持version和timestamp呢,在提交的过程中,只需将version或者timestramp进行更新即可。

 

    2、在高并发情况下,如何高效、健康地给select 语句加上行锁?

 

    高并发情况下,简单地添加行锁,数据库可能会支持不住,可以:
    (1)对请求做个队列,先进先出,不会重复,但是速度上会不会变慢?
    (2)避免实时读取数据库,把数据缓存起来;数据用队列装起来,读走就没了。也可以单独启用一个线程,采用异步方式实现;
    (3)环境中有Redis的话直接使用自带的队列接口就行,按一定顺序装进去,取得时候是原子操作,取完就没有了。

 

    3、SQL Server是如何控制并发冲突的?

 

    悲观与乐观机制下,数据库设定了隔离级别:
    SQL Server2005及以上版本支持5种隔离级别来控制冲突。其中三种只在悲观并发模式中使用,一种只在乐观并发模式中使用,另一个可以在两种模式中使用。


   (1)未提交读(Uncommitted Read)
    未提交读只能防止“丢失更新”问题,其它问题不能防止。
    未提交读是针对阻塞太频繁的悲观并发控制,因为它只是忽略了锁,而不保障事务的一致性。
   (2)已提交读(Read Committed)
    已提交读既可以是乐观的也可以是悲观的,这取决于数据 库的read_committed_snapshot设置。默认情况下这个 选项是关闭的,所以该隔离级别默认情况下是采用悲观并发控制。
    已提交读可以防止脏读问题。
   (3)可重复读(Repeatable Read)
    可重复读是一种悲观的隔离级别。它在已提交读的基础上增加了新特性:确保当事务重新访问数据或查询被再一次执行时,数据将不会再发生改变。
    可重复读不但可以防止脏读问题,还可以防止不可重复读问题,但是不能防止幻读问题。
    注意,可重复读的资源开销是很大的,事务中所有的数据必须等待事务完成之后才能访问。
   (4)快照(Snapshot)
    快照是一种乐观隔离级别。
    Snapshot事务中任何语句所读取的记录,都是事务启动时的数据。
    这相当于事务启动时,数据库为事务生成了一份专用“快照”。
    在当前事务中看到不其它事务在当前事务启动之后所进行的数据修改。
    Snapshot事务不会读取记录时要求锁定,读取记录的Snapshot事务不会锁住其它事务写入记录,写入记录的事务也不会锁住Snapshot事务读取数据。
    快照隔离级别的事务不是串行执行的,两个进程同时使用快照隔离,如果它们执行多次,可能最终产生的结果不会一致。(这段话要证实)
   (5)可串行化(Serializable)
    可串行化是一种悲观隔离级别。它在可重复读的基础上增加了新的特性:确保在两次查询的中间,不会增加新的行。
    可串行化是最健壮的悲观隔离级别,因为它防止了并发冲突产生的4个问题。
    可串行化也是资源开销最大的措施。当使用可串行化隔离时,如果SQL的条件字段没有索引,那么SQL Server会产生表级锁。

 

posted @ 2017-03-18 09:52 左正 阅读( 137) 评论( 0) 编辑 收藏
 

公告本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/6571574.html/,如需转载请自行联系原作者

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
4月前
|
存储 Java
高并发编程之多线程锁和Callable&Future 接口
高并发编程之多线程锁和Callable&Future 接口
66 1
|
4月前
|
Java
在高并发环境下,再次认识java 锁
在高并发环境下,再次认识java 锁
59 0
|
2月前
|
SQL 关系型数据库 MySQL
(八)MySQL锁机制:高并发场景下该如何保证数据读写的安全性?
锁!这个词汇在编程中出现的次数尤为频繁,几乎主流的编程语言都会具备完善的锁机制,在数据库中也并不例外,为什么呢?这里牵扯到一个关键词:高并发,由于现在的计算机领域几乎都是多核机器,因此再编写单线程的应用自然无法将机器性能发挥到最大,想要让程序的并发性越高,多线程技术自然就呼之欲出,多线程技术一方面能充分压榨CPU资源,另一方面也能提升程序的并发支持性。
186 3
|
4月前
|
Java
高并发编程之JUC 三大辅助类和读写锁
高并发编程之JUC 三大辅助类和读写锁
44 1
|
4月前
|
缓存 NoSQL 数据库
关于高并发下缓存失效的问题(本地锁 && 分布式锁 && Redission 详解)
关于高并发下缓存失效的问题(本地锁 && 分布式锁 && Redission 详解)
220 0
高并发服务优化篇:详解一次由读写锁引起的内存泄漏
JVM相关的异常,一直是一线研发比较头疼的问题。因为对于业务代码,JVM的运行基本算是黑盒,当异常发生时,较难直观地看到和找到问题所在,这也是我们一直要研究其内部逻辑的原因。
|
设计模式 Java 容器
一篇神文就把java多线程,锁,JMM,JUC和高并发设计模式讲明白了
今天给大家分享一篇一线开发大牛整理的java高并发核心编程神仙文档,里面主要包含的知识点有:多线程、线程池、内置锁、JMM、CAS、JUC、高并发设计模式、Java异步回调、CompletableFuture类等。
|
存储 SQL Oracle
解析 MySQL 锁机制:共享锁、排它锁、间隙锁、意向锁等,保障数据安全与高并发的秘密武器
解析 MySQL 锁机制:共享锁、排它锁、间隙锁、意向锁等,保障数据安全与高并发的秘密武器
358 1
|
Java 测试技术
高并发编程-自定义带有超时功能的锁
高并发编程-自定义带有超时功能的锁
52 0
|
存储 Java 程序员
【多线程与高并发】- synchronized锁的认知
synchronized 是 Java 语言的一个关键字,它允许多个线程同时访问共享的资源,以避免多线程编程中的竞争条件和死锁问题。
121 0
【多线程与高并发】- synchronized锁的认知