搜索
首页数据库mysql教程hibernate中的乐观锁和悲观锁

hibernate支持两种锁:悲观锁(Pessimistic Locking)和乐观锁(Optimistic Locking) 悲观锁:指的是对数据库数据被外界的修改持保守态度(无论是本系统的事务处理,或者是外部系统的事务处理),在整个数据处理的过程数据都处于锁定的状态。hibernate中的

hibernate支持两种锁:悲观锁(Pessimistic Locking)和乐观锁(Optimistic Locking)

悲观锁:指的是对数据库数据被外界的修改持保守态度(无论是本系统的事务处理,或者是外部系统的事务处理),在整个数据处理的过程数据都处于锁定的状态。hibernate中的悲观锁,是依靠数据库中的锁机制(因为只有数据库层才能控制本系统和外部系统对数据库的数据操作)。

例如”select * from user where userName=’Johnson’ for update“这条sql锁定了user表中所有userName=’Johnson’的记录,本次事务提交之前,外界无法修改这些记录。

hibernate中的悲观锁,也是基于数据库的锁机制实现的。

<code class=" hljs lasso"><span class="hljs-built_in">String</span> hqlStr <span class="hljs-subst">=</span><span class="hljs-string">"from TUser as user where user.name='Lili'"</span>;
Query query <span class="hljs-subst">=</span> session<span class="hljs-built_in">.</span>createQuery(hqlStr);
query<span class="hljs-built_in">.</span>setLockMode(<span class="hljs-string">"user"</span>,LockMode<span class="hljs-built_in">.</span>UPGRADE); <span class="hljs-comment">//加锁</span>
<span class="hljs-built_in">List</span> userList <span class="hljs-subst">=</span> query<span class="hljs-built_in">.</span><span class="hljs-built_in">list</span>();<span class="hljs-comment">//执行查询,获取数据</span></code>

上面的代码中setLockMode第一个参数指定了别名为user的返回的记录进行上锁。
生成的sql为:

<code class=" hljs applescript">select tuser0_.<span class="hljs-property">id</span> <span class="hljs-keyword">as</span> <span class="hljs-property">id</span>, tuser0_.<span class="hljs-property">name</span> <span class="hljs-keyword">as</span> <span class="hljs-property">name</span>, tuser0_.group_id
<span class="hljs-keyword">as</span> group_id, tuser0_.user_type <span class="hljs-keyword">as</span> user_type, tuser0_.sex <span class="hljs-keyword">as</span> sex
<span class="hljs-keyword">from</span> t_user tuser0_ <span class="hljs-keyword">where</span> (tuser0_.<span class="hljs-property">name</span>='Erica' ) <span class="hljs-keyword">for</span> update</code>

可见hibernate通过数据库中的for update子句实现悲观锁机制。
hibernate的加锁模式:
LockMode.NONE : 无锁机制。
LockMode.WRITE : Hibernate 在 Insert 和 Update 记录的时候会自动获取。
LockMode.READ : Hibernate 在读取记录的时候会自动获取。
以上这三种锁机制一般由 Hibernate 内部使用,如 Hibernate 为了保证 Update过程中对象不会被外界修改,会在 save 方法实现中自动为目标对象加上 WRITE 锁。
LockMode.UPGRADE :利用数据库的 for update 子句加锁。
LockMode. UPGRADE_NOWAIT : Oracle 的特定实现,利用 Oracle 的 for update nowait 子句实现加锁。
上面这两种锁机制是我们在应用层较为常用的,加锁一般通过以下方法实现:
Criteria.setLockMode
Query.setLockMode
Session.lock

相对于悲观锁,乐观锁的锁机制就显得比较宽松。悲观锁大部分情况依靠数据库的锁机制实现,来保证最大程度的独占性。但另一方面数据库的开销非常大,尤其对于长事务来说。

乐观锁大部分是基于数据版本(version)记录机制实现。即在数据表中增加一个版本标识,读取出数据时,连带这个版本标识一起读出,更新数据的时候,把版本标识加1。将提交版本数据跟数据库中当前版本信息对比,如果提交的数据中版本号大于数据表当前的版本号,则允许更新,否则认为是过期数据。

hibernate的乐观锁主要有两种方式:version和时间戳

举个配置的例子:

<code class=" hljs xml">    <span class="hljs-pi"><?xml version="1.0"?></span>  
    <span class="hljs-doctype"><!DOCTYPE hibernate-mapping PUBLIC  
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"></span>  
    <span class="hljs-tag"><<span class="hljs-title">hibernate-mapping</span>></span>  
        <span class="hljs-tag"><<span class="hljs-title">class</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"test.Dir"</span> <span class="hljs-attribute">table</span>=<span class="hljs-value">"t_dir"</span>></span>  
            <span class="hljs-tag"><<span class="hljs-title">id</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"id"</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"string"</span> <span class="hljs-attribute">unsaved-value</span>=<span class="hljs-value">"null"</span>></span>  
             <span class="hljs-tag"><<span class="hljs-title">column</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"id_"</span> <span class="hljs-attribute">sql-type</span>=<span class="hljs-value">"char(32)"</span> <span class="hljs-attribute">not-null</span>=<span class="hljs-value">"true"</span> /></span>  
             <span class="hljs-tag"><<span class="hljs-title">generator</span> <span class="hljs-attribute">class</span>=<span class="hljs-value">"uuid.hex"</span> /></span>  
        <span class="hljs-tag"></<span class="hljs-title">id</span>></span>  
        <span class="hljs-comment"><!--这里version节点必须要配在id之后--></span>
            <span class="hljs-tag"><<span class="hljs-title">version</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"version_"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"version"</span> /></span>  
            <span class="hljs-tag"><<span class="hljs-title">property</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"name"</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"name_"</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"string"</span>/></span>  
            <span class="hljs-tag"><<span class="hljs-title">property</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"size"</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"size_"</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"long"</span> /></span>  
            <span class="hljs-tag"><<span class="hljs-title">many-to-one</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"dir"</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"pid_"</span> <span class="hljs-attribute">class</span>=<span class="hljs-value">"test.Dir"</span> /></span>  
        <span class="hljs-tag"></<span class="hljs-title">class</span>></span>  
    <span class="hljs-tag"></<span class="hljs-title">hibernate-mapping</span>></span>  </code>

乐观锁带来的负面问题:如果两个不同的事务同时读取一条数据并进行更新时,程序会报异常:org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)。这时候就要捕获异常,然后处理并提醒用户再次提交。
同样,乐观锁也有局限性。就是只控制了本系统的事务并发操作,而外部系统对数据表的操作却无法控制,此时有个解决办法就是:在存储过程里实现乐观锁机制,这样无论是本系统或是外部系统的事务操作,数据库都可以控制。所以,在设计阶段,尽量考虑到各种情况,究竟是在程序端实现好,还是数据库端实现比较好。

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
解释InnoDB缓冲池及其对性能的重要性。解释InnoDB缓冲池及其对性能的重要性。Apr 19, 2025 am 12:24 AM

InnoDBBufferPool通过缓存数据和索引页来减少磁盘I/O,提升数据库性能。其工作原理包括:1.数据读取:从BufferPool中读取数据;2.数据写入:修改数据后写入BufferPool并定期刷新到磁盘;3.缓存管理:使用LRU算法管理缓存页;4.预读机制:提前加载相邻数据页。通过调整BufferPool大小和使用多个实例,可以优化数据库性能。

MySQL与其他编程语言:一种比较MySQL与其他编程语言:一种比较Apr 19, 2025 am 12:22 AM

MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。 MySQL以其高性能、可扩展性和跨平台支持着称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

学习MySQL:新用户的分步指南学习MySQL:新用户的分步指南Apr 19, 2025 am 12:19 AM

MySQL值得学习,因为它是强大的开源数据库管理系统,适用于数据存储、管理和分析。1)MySQL是关系型数据库,使用SQL操作数据,适合结构化数据管理。2)SQL语言是与MySQL交互的关键,支持CRUD操作。3)MySQL的工作原理包括客户端/服务器架构、存储引擎和查询优化器。4)基本用法包括创建数据库和表,高级用法涉及使用JOIN连接表。5)常见错误包括语法错误和权限问题,调试技巧包括检查语法和使用EXPLAIN命令。6)性能优化涉及使用索引、优化SQL语句和定期维护数据库。

MySQL:初学者的基本技能MySQL:初学者的基本技能Apr 18, 2025 am 12:24 AM

MySQL适合初学者学习数据库技能。1.安装MySQL服务器和客户端工具。2.理解基本SQL查询,如SELECT。3.掌握数据操作:创建表、插入、更新、删除数据。4.学习高级技巧:子查询和窗口函数。5.调试和优化:检查语法、使用索引、避免SELECT*,并使用LIMIT。

MySQL:结构化数据和关系数据库MySQL:结构化数据和关系数据库Apr 18, 2025 am 12:22 AM

MySQL通过表结构和SQL查询高效管理结构化数据,并通过外键实现表间关系。1.创建表时定义数据格式和类型。2.使用外键建立表间关系。3.通过索引和查询优化提高性能。4.定期备份和监控数据库确保数据安全和性能优化。

MySQL:解释的关键功能和功能MySQL:解释的关键功能和功能Apr 18, 2025 am 12:17 AM

MySQL是一个开源的关系型数据库管理系统,广泛应用于Web开发。它的关键特性包括:1.支持多种存储引擎,如InnoDB和MyISAM,适用于不同场景;2.提供主从复制功能,利于负载均衡和数据备份;3.通过查询优化和索引使用提高查询效率。

SQL的目的:与MySQL数据库进行交互SQL的目的:与MySQL数据库进行交互Apr 18, 2025 am 12:12 AM

SQL用于与MySQL数据库交互,实现数据的增、删、改、查及数据库设计。1)SQL通过SELECT、INSERT、UPDATE、DELETE语句进行数据操作;2)使用CREATE、ALTER、DROP语句进行数据库设计和管理;3)复杂查询和数据分析通过SQL实现,提升业务决策效率。

初学者的MySQL:开始数据库管理初学者的MySQL:开始数据库管理Apr 18, 2025 am 12:10 AM

MySQL的基本操作包括创建数据库、表格,及使用SQL进行数据的CRUD操作。1.创建数据库:CREATEDATABASEmy_first_db;2.创建表格:CREATETABLEbooks(idINTAUTO_INCREMENTPRIMARYKEY,titleVARCHAR(100)NOTNULL,authorVARCHAR(100)NOTNULL,published_yearINT);3.插入数据:INSERTINTObooks(title,author,published_year)VA

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。