高并发与锁

本文涉及的产品
云数据库 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
相关文章
|
3月前
多线程并发锁的方案—原子操作
多线程并发锁的方案—原子操作
|
3月前
多线程并发锁方案—自旋锁
多线程并发锁方案—自旋锁
|
3月前
多线程并发锁的方案—互斥锁
多线程并发锁的方案—互斥锁
|
7月前
|
调度 C++
C++中的锁机制
C++中的锁机制
|
8月前
|
设计模式
【并发技术04】线程技术之死锁问题
【并发技术04】线程技术之死锁问题
|
11月前
|
安全 Java 调度
认识并发中常见的锁
1. 锁的作用 2. 乐观锁和悲观锁 1)乐观锁 2)悲观锁 3)乐观锁和悲观锁在 Java 中的典型实现 4)数据版本机制 3. CAS 机制 1)什么是 CAS 2)CAS 的 ABA 问题 4. 读写锁 1)Java 标准库中提供的读写锁 5. 偏向锁、轻量级锁和重量级锁 1)偏向锁 2)轻量级锁 3)重量级锁 6. 自旋锁 7. 公平锁和非公平锁
91 0
|
11月前
|
Java
多线程并发情况下的数据一致性问题
多线程并发情况下的数据一致性问题
137 0
|
存储 Java 程序员
【多线程与高并发】- synchronized锁的认知
synchronized 是 Java 语言的一个关键字,它允许多个线程同时访问共享的资源,以避免多线程编程中的竞争条件和死锁问题。
106 0
【多线程与高并发】- synchronized锁的认知
|
SQL 存储 人工智能
|
存储 缓存 Java
并发场景加锁优化小技巧
在 JDK 中有很多锁,包括 synchronized、ReentrantLock、ReentrantReadWriteLock、锁的使用场景也分很多种,下面看一下对加锁优化的小技巧。
117 0