`
zhouchaofei2010
  • 浏览: 1085845 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

使用悲观琐和乐观锁解决事务并发问题

 
阅读更多

 摘自:http://www.cnblogs.com/otomedaybreak/archive/2012/01/27/2330008.html#C5

五、使用悲观锁解决事务并发问题

  悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

  一个典型的依赖数据库的悲观锁调用:select * from account where name=”Erica” for update这条 sql 语句锁定了 account 表中所有符合检索条件( name=”Erica” )的记录。本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。悲观锁,也是基于数据库的锁机制实现。

在Hibernate使用悲观锁十分容易,但实际应用中悲观锁是很少被使用的,因为它大大限制了并发性:

图为Hibernate3.6的帮助文档Session文档的get方法截图,可以看到get方法第三个参数"lockMode"或"lockOptions",注意在Hibernate3.6以上的版本中"LockMode"已经不建议使用。方法的第三个参数就是用来设置悲观锁的,使用第三个参数之后,我们每次发送的SQL语句都会加上"for update"用于告诉数据库锁定相关数据。

LockMode参数选择该选项,就会开启悲观锁。

  T1,T2时刻取款事务和转账事务分别开启,T3事务查询ACCOUNTS表的数据并用悲观锁锁定,T4转账事务也要查询同一条数据,数据库发现该记录已经被前一个事务使用悲观锁锁定了,然后让转账事务等待直到取款事务提交。T6时刻取款事务提交,T7时刻转账事务获取数据。

 

六、使用乐观锁解决事务并发问题

  相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本(Version)记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个"version"字段来实现。
  乐观锁的工作原理:读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

Hibernate为乐观锁提供了3中实现:

1. 基于version

2. 基于timestamp

3. 为遗留项目添加添加乐观锁 

配置基于version的乐观锁:

复制代码
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.suxiaolei.hibernate.pojos.People" table="people">
<id name="id" type="string">
<column name="id"></column>
<generator class="uuid"></generator>
</id>

<!-- version标签用于指定表示版本号的字段信息 -->
<version name="version" column="version" type="integer"></version>

<property name="name" column="name" type="string"></property>

</class>
</hibernate-mapping>
复制代码

配置基于timestamp的乐观锁:

复制代码
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.suxiaolei.hibernate.pojos.People" table="people">
<id name="id" type="string">
<column name="id"></column>
<generator class="uuid"></generator>
</id>

<!-- timestamp标签用于指定表示版本号的字段信息 -->
<timestamp name="updateDate" column="updateDate"></timestamp>

<property name="name" column="name" type="string"></property>

</class>
</hibernate-mapping>
复制代码

遗留项目,由于各种原因无法为原有的数据库添加"version"或"timestamp"字段,这时不可以使用上面两种方式配置乐观锁,Hibernate为这种情况提供了一个"optimisitic-lock"属性,它位于<class>标签上:

复制代码
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.suxiaolei.hibernate.pojos.People" table="people" optimistic-lock="all">
<id name="id" type="string">
<column name="id"></column>
<generator class="uuid"></generator>
</id>

<property name="name" column="name" type="string"></property>
</class>
</hibernate-mapping>
复制代码

将该属性的值设置为all,让该记录所有的字段都为版本控制信息。

分享到:
评论

相关推荐

    MySQL中的悲观锁与乐观锁

    在关系型数据库中,悲观锁与乐观锁是解决资源并发场景的解决方案,接下来将详细讲解:magnifying_glass_tilted_right:一下这两个并发解决方案的实际使用及优缺点。 首先定义一下数据库,做一个最简单的库存表,如下...

    基于Django的乐观锁与悲观锁解决订单并发问题详解

    在解释如何解决订单并发问题之前,需要先了解一下什么是数据库的事务。(我用的是mysql数据库,这里以mysql为例) 1) 事务概念 一组mysql语句,要么执行,要么全不不执行。  2) mysql事务隔离级别 Read Committed...

    SQL数据库系统原理(二)———乐观锁与悲观锁、MVCC、范式理论、SQL和NoSQL比较

    封锁的类型以及粒度,两段锁协议,隐式和显式锁定 封锁类型有两种:读写锁和意向锁 读写锁分类读锁(s锁)和写锁(x锁)。...乐观锁和悲观锁都是为了事务的并发控制。 乐观锁 悲观锁 目的 事务

    实例讲解MySQL中乐观锁和悲观锁

    乐观锁和悲观锁式并发控制主要采用的技术手段 悲观锁 在关系数据库管理系统中,悲观并发控制(悲观锁,PCC)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作的每...

    深入理解Yii2.0乐观锁与悲观锁的原理与使用

    本文介绍了深入理解Yii2.0乐观锁与悲观锁的原理与使用,分享给大家,具体如下: Web应用往往面临多用户环境,这种情况下的并发写入控制...但是,就于具体开发过程而言,一般分为悲观锁和乐观锁两种方式来解决并发冲突问

    hibernate的三锁

    该资源主要是分析:乐观锁解决事务并发.乐观锁校验测试, 基于hiber管理的悲观锁实现

    解析数据库锁协议和InnoDB的锁机制(全面解析行级锁、表级锁、排他锁、共享锁、悲观锁、乐观锁等常用锁)

    数据库通过锁以及锁协议来进行并发控制,解决并发事务带来的问题,本篇博文主要是解析数据库的锁协议和Mysql的默认存储引擎InnoDB的锁机制。 如果对事务隔离级别以及并发事务带来的问题不熟悉可以翻阅我的另外一篇...

    高并发场景防止库存数量超卖少卖

    乐观锁:通过在库存记录中增加版本号字段,更新时验证版本号是否改变,若改变则表示库存已被其他事务修改,避免了长时间锁等待,但需合理设计重试策略。 Redis:利用Redis的高速与原子操作特性,将库存存入Redis中...

    MySQL数据库锁机制原理解析

    为了更好的应对高并发,封锁、时间戳、乐观并发控制(乐观锁)、悲观并发控制(悲观锁)都是并发控制采用的主要技术方式。 锁分类 ①、按操作划分:DML锁,DDL锁 ②、按锁的粒度划分:表级锁、行级锁、页级锁 ③、...

    【RocksDB】TransactionDB源码分析.docx

    RocksDB的Transaction分为两类:Pessimistic和Optimistic,类似悲观锁和乐观锁的区别,PessimisticTransaction的冲突检测和加锁是在事务中每次写操作之前做的(commit后释放),如果失败则该操作失败;...

    SQL 事务与锁 详解

    本篇博客旨在记录数据库中事务与锁机制的必要性,记录了如何在数据库中使用事务与锁机制实现数据库的一致性以及并发性。... 悲观锁与乐观锁3. 事务的ACID特性3.1. ACID特性3.2. 事务的隔离级别与并发问题3.

    资源竞争与并发控制

    非常浅显的讲述《资源竞争与并发控制》。 1.应用层并发控制?不是重点 ...乐观锁与悲观锁 3.隔离级别:脏读Dirty Read+幻读Phantom Read 4.InnoDB锁与多版本控制? 5.意向锁? 6.事务传播行为?

    27道高级开发数据库面试题目以及答案.pdf

    描述一下mysql的乐观锁和悲观锁,以及mysql锁的种类; mysql如何做分库分表的; mysql描述一下mysql主从复制的机制的原理;mysql主从复制主要有几种模式 在mysql开启Binlog(为了其他非事务引擎复制所以引入binlog,...

    POJOs.in.Action

    《POJOS IN ACTION中文版:用轻量级框架开发企业应用》是一本实践指南,它围绕POJO...此外,《POJOS IN ACTION中文版:用轻量级框架开发企业应用》还详尽地分析了事务管理、悲观锁、乐观锁、条件组合搜索等难点问题。

    聊聊高并发高可用那些事(Kafka、Redis、MySQL)

    - 乐观锁和悲观锁 - 分库、分表、分区 - 存储过程、定时任务 - MySQL 视图 (VIEW) - Redis 和 MySQL 双写一致性 - 高并发高可用方案 - Join语句还能不能用? - 主从同步有延迟怎么办? - .frm .myi .myd .ibd 文件 - ...

    常见(MySQL)面试题(含答案).docx

    数据库悲观锁和乐观锁的原理和应用场景? 如何做 MySQL 的性能优化? 索引是什么?MySQL为什么使用B+树,而不是使用其他?B+树的特点 创建索引时需要注意什么? CHAR和VARCHAR的区别? NOW()和CURRENT_DATE()有...

    Mysql面试题总结大全

    乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。 乐观锁与悲观锁的具体区别 8、数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询,更新数据库表中数据。索引的实现通常...

    mysql面试题100题,包含答案和解析.docx

    13、数据库的乐观锁和悲观锁。 14、SQL优化的一般步骤是什么,怎么看执行计划(explain),如何理解其中各个字段的含义。 15、select for update有什么含义,会锁表还是锁行还是其他。 16、MySQL事务得四大特性以及...

Global site tag (gtag.js) - Google Analytics