事务需要保证原子性(Atomicity)、一致性(Consistence)、隔离性(Isolation behavior)、持续性(Durability),简称ACID。
原子性:一个事务内的操作要么全部成功,要么全部失败回滚。
一致性:事务内的数据,如果事务成功,则必须都是成功后的状态,如果失败,则必须都是最开始的状态,不能有的是成功后的状态,有的是开始的状态。
隔离性:在多个事务同时进行的情况下,互相不能干扰。
持续性:事务一旦成功,则事务成功的结果必须保存下来。
事务可以由声明式事务和编程式事务,声明式的事务由容器所提供的服务,可以在配置文件中定义事务边界、隔离级别等。
编程式事务是直接使用JDBC或者相关框架的API,以编写代码的方式,可以更细致的定义事务边界、隔离级别等。
下面重点介绍下事务的隔离性怎么保证。
在数据库中保证隔离性最基本的方式就是锁定数据库,或者被更新、读取的表、列,如果数据库不锁定数据会发生的事:
1.lost update
事务A更新某条数据
事务B更新某条数据
事务B commit
事务A commit
事务A的更新就丢失了。
2.dirty read
事务A更新某条数据
事务B读取该条数据
事务A commit
事务B commit
这种情况下事务B读的就是脏数据。
3.unrepeatable read
事务A读取某条数据
事务B更新了数据
事务B commit
事务A再次读取数据
这时A两次读取的结果就不一样
4.phantom read
事务A查询到了5条数据
事务B更新了相关联的表
事务B commit
事务A再次查询只得到了4条数据
这次事务A就是幻读了
为了解决上面的4种问题,就出现了4种隔离级别,不同的数据库默认使用不同的隔离级别
1.read uncommit
当事务A更新某条数据时,不容许其他事务来更新该数据,但可以读取。
2.read commit
当事务A更新某条数据时,不容许其他事务进行任何操作包括读取,但事务A读取时,其他事务可以进行读取、更新
3.read repeatable
当事务A更新数据时,不容许其他事务进行任何操作,但当事务A进行读取时,其他事务只能读取,不能更新。
4.serializable
最严格的隔离级别,事务必须依次进行。
Hibernate乐观锁策略,认为很少出现同时读取、更新的情况,在数据库隔离级别一般设为read commit,会导致出现lost update的问题
对于lost update问题,有3种解决策略:
先更新为主:两个事务同时更新,但后提交的事务将抛出exception,后面的事务必须重新获取数据
后更新为主:后提交的事务直接覆盖先提交的。
合并冲突:后提交的数据会得到提示,只更新没有冲突的列
Hibernate推荐我们使用先更新为主,是通过version来实现的,即读取数据的时候会得到一个version值,提交时会将这个version值和数据库中的相比,如果一样则证明可以成功提交,并同时将version+1。
实现version可以在对象模型中加一个version属性,并在关系模型加一个version列,也可以配置让hibernate通过比较对象所有的属性来确实是否是可以更新。
Hibernate悲观锁策略,认为会经常出现同时读取、更新的情况;
List users1 = query.list();
query.setLockMode("user", LockMode.UPGRADE);
hibernate通过锁定数据来避免lost update的问题。
在Hibernate配置文件中设置隔离级别:
JDBC连接数据库使用的是默认隔离级别,即读操作已提交(Read Committed)和可重读(Repeatable Read)。在Hibernate的配置文件hibernate.properties中,可以修改隔离级别:
1:读操作未提交(Read Uncommitted) 2:读操作已提交(Read Committed) 4:可重读(Repeatable Read) 8:可串行化(Serializable)
<property name=” hibernate.connection.isolation”>4</property>
Oracle 数据隔离级别设置
Oracle数据库支持READ COMMITTED 和 SERIALIZABLE这两种事务隔离级别。所以Oracle不支持脏读SQL标准所定义的默认事务隔离级别是SERIALIZABLE,但是Oracle 默认使用的是READ COMMITTED;
设置隔离级别使用 SET TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]
相关推荐
Hibernate的乐观锁与悲观锁的文档,帮助学习Hibernate的乐观锁与悲观锁,让你们学得更轻松。
Hibernate乐观锁和悲观锁分析,针对在使用HIBERNATE时怎么配置乐观锁进行了详细的范例讲解
Hibernate 事物隔离级别 深入探究
hibernate的乐观锁和悲观锁,两种锁搞定一切
Hibernate锁机制_悲观锁和乐观锁
NULL 博文链接:https://cdxs2.iteye.com/blog/1938245
其中通过 version 实现的乐观锁机制是 Hibernate 官方推荐的乐观锁实现,同时也是 Hibernate 中,目前唯一在数据对象脱离 Session 发生修改的情况下依然有效的锁机制。因此,一般情况下,我们都选择 version 方式...
NULL 博文链接:https://12345678.iteye.com/blog/721836
Hibernate高级特性,悲观锁与乐观锁的应用和区别,及两者之间的区别。
很好的描述Hibernate的悲观锁和乐观锁,
主要介绍了Hibernate实现悲观锁和乐观锁的有关内容,涉及hibernate的隔离机制,以及实现悲观锁和乐观锁的代码实现,需要的朋友可以了解下。
Spring控制Hibernate中的事务传播特性与隔离级别操作,通过利用spring和Hibernate的两个HibernateTemplate 和 jdbcTemplate类,实现数据的交互。
性能------------缓存 延迟加载 事务 悲观 乐观锁
(3)隔离性:代表的是一个事务执行的过程当中,不应该受到其他事务的干扰。 (4)持久性:代表一个事务执行完成后数据就持久到数据库当中(提交或回滚)。 3、如果我们不考虑事务的隔离性,就会引发一些安全性的...
求助编辑百科名片相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库 性能的大量开销,特别是对长事务而言,...
学习hibernate的必备知识,当你学习hibernate时,就会对锁的概念有一定的了解了.
spring整合hibernate实现事务处理 1.spring整合hibernate实现事务处理-注解方式 2.spring整合hibernate实现事务处理-XML方式
主要介绍了Hibernate悲观锁和乐观锁实例详解,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下