第一类丢失更新(Lost Update)
时间 |
取款事务A |
存款事务B |
T1 |
开始事务 |
|
T2 |
|
开始事务 |
T3 |
查询账户余额为1000元 |
|
T4 |
|
查询账户余额为1000元 |
T5 |
|
汇入100元把余额改为1100元 |
T6 |
|
提交事务 |
T7 |
取出100元把余额改为900 元 |
|
T8 |
撤销事务 |
|
T9 |
余额恢复为1000元(丢失更新) |
|
dirty read脏读(读到了另一个事务在处理中还未提交的数据)
时间 |
取款事务A |
存款事务B |
T1 |
开始事务 |
|
T2 |
|
开始事务 |
T3 |
|
查询账户余额为1000元 |
T4 |
|
汇入100元把余额改为1100元 |
T5 |
查询账户余额为1100元(读取脏数据) |
|
T6 |
|
回滚 |
T7 |
取款1100 |
|
T8 |
提交事务失败 |
|
non-repeatable read 不可重复读
时间 |
取款事务A |
存款事务B |
T1 |
开始事务 |
|
T2 |
|
开始事务 |
T3 |
查询账户余额为1000元 |
|
T5 |
|
汇入100元把余额改为1100元 |
T5 |
|
提交事务 |
T6 |
查询帐户余额为1100元 |
|
T8 |
提交事务 |
|
second lost update problem 第二类丢失更新(不可重复读的特殊情况)
时间 |
取款事务A |
存款事务B |
T1 |
|
开始事务 |
T2 |
开始事务 |
|
T3 |
|
查询账户余额为1000元 |
T4 |
查询账户余额为1000元 |
|
T5 |
|
取出100元把余额改为900元 |
T6 |
|
提交事务 |
T7 |
汇入100元 |
|
T8 |
提交事务 |
|
T9 |
把余额改为1100元(丢失更新) |
|
phantom read 幻读
时间 |
查询学生事务A |
插入新学生事务B |
T1 |
开 始事务 |
|
T2 |
|
开始事务 |
T3 |
查 询学生为10人 |
|
T4 |
|
插入1个学生 |
T5 |
查 询学生为11人 |
|
T6 |
|
提交事务 |
T7 |
提 交事务 |
|
2、数据库的事务隔离机制
查看 java.sql.Connection 文档
1:read-uncommitted 2:read-committed 4:repeatable read 8:serializable(数字代表对应值)
为什么取值要使用 1 2 4 8 而不是 1 2 3 4
1=0000 2=0010 4=0100 8=1000(位移计算效率高)
(1)只要数据库支持事务,就不可能出现第一类丢失更新
(2)read-uncommitted(允许读取未提交的数据) 会出现dirty read, phantom-read,
non-repeatable read 问题
(3)read-commited(读取已提交的数据 项目中一般都使用这个)不会出现dirty read,因为只有另
一个事务提交才会读出来结果,但仍然会出现 non-repeatable read 和 phantom-read
使用read-commited机制可用悲观锁 乐观锁来解决non-repeatable read 和 phantom-read问题
(4)repeatable read(事务执行中其他事务无法执行修改或插入操作 较安全)
(5)serializable解决一切问题(顺序执行事务 不并发,实际中很少用)
3、设定hibernate的事务隔离级别(使用hibernate.connection.isolation配置 取值1、2、4、8)
(1)hibernate.connection.isolation = 2(如果不设 默认依赖数据库本身的级别)
(2)用悲观锁解决repeatable read的问题(依赖于数据库的锁)
a、select ... for update
b、使用另一种load方法--load(xx.class , i , LockMode.Upgrade)
LockMode.None无锁的机制,Transaction结束时,切换到此模式
LockMode.read在査询的时候hibernate会自动获取锁
LockMode.write insert update hibernate 会自动获取锁
以上3种锁的模式,是hibernate内部使用的(不需要设)
LockMode.UPGRADE_NOWAIT是 ORACLE 支持的锁的方式
(3)Hibernate(JPA)乐观锁定(ReadCommitted)
实体类中增加version属性(数据库也会对应生成该字段,初始值为0),并在其get方法前加
@Version注解,则在操作过程中每更新一次该行数据则version值加1,即可在事务提交前判断该数据是否
被其他事务修改过。如果实体version和数据库里面的version不一样,
那么在事务提交的时候就会报错,就知道该记录已经更新过,再采取某种措施。
相关推荐
【Hibernate乐观锁与悲观锁详解】 在开发过程中,尤其是在并发环境下,确保数据的一致性和完整性至关重要。Hibernate,作为Java领域广泛使用的ORM框架,提供了一种处理并发数据访问冲突的手段,那就是锁机制。主要...
在处理并发问题时,Hibernate提供了悲观锁和乐观锁两种机制。 悲观锁假设并发环境中的冲突是常态,因此在读取数据时就立即锁定,直到事务结束才释放。在Hibernate中,可以通过设置`@LockModeType.PESSIMISTIC_READ`...
在Java的持久化框架Hibernate中,悲观锁和乐观锁是两种重要的并发控制策略,它们用于管理数据库中的数据在多线程环境下的访问安全。本文将深入探讨这两种锁机制的原理、应用场景及其区别。 首先,我们来理解悲观锁...
Hibernate 的隔离机制是基于数据库的事务隔离级别的。 Hibernate 提供了四种隔离机制: 1. Read Uncommitted:能够读取未提交的数据,允许脏读的存在。 2. Read Committed:不会出现脏读,因为只有另一个事务提交才...
- **悲观锁**:在读取数据时就锁定资源,防止其他事务修改,直至事务结束释放锁。Hibernate通过`@Lock`注解配合`LockModeType`实现悲观锁。 **5. 事务的回滚规则** - 任何未捕获的`HibernateException`或`JDBC...
例如,对于读多写少的场景,乐观锁和较高的事务隔离级别(如Repeatable Read)可能是更好的选择。而对于写操作频繁的情况,悲观锁和更低的隔离级别可能更合适。 总的来说,理解并熟练掌握Hibernate的事务和并发控制...
Hibernate提供了四种事务隔离级别:读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE)。开发者可以根据应用场景选择合适的隔离级别。此外,...
以上只是Hibernate众多知识点的一部分,实际面试中可能涉及更多细节,如级联操作、事务隔离级别、延迟加载机制、乐观锁和悲观锁的区别等。熟悉并理解这些内容对于通过Hibernate相关的面试至关重要。
1. **悲观锁与乐观锁** - 悲观锁:在读取数据时就假设会发生并发冲突,因此在读取时会立即加锁,防止其他事务修改数据。在Hibernate中,悲观锁主要通过`LockMode.UPGRADE`实现,即使用`SELECT ... FOR UPDATE`语句...
#### 二、Hibernate事务管理机制 Hibernate 本身不实现事务逻辑,而是依赖于底层的数据源(JDBC 或 JTA)来实现事务管理。这意味着,当你使用 Hibernate 进行数据操作时,所涉及的事务要么基于 JDBC 的事务管理,要么...
在 Hibernate 中,可以通过设置 hibernate.connection.isolation 属性来指定事务隔离级别。 例如: ```xml <property name="hibernate.connection.isolation">2 ``` 这将设置事务隔离级别为 READ_COMMITTED。 解决...
同时,还要注意合理配置事务隔离级别,如读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE),以平衡数据一致性与性能。 总之,深入学习和掌握...
#### 二、Hibernate事务管理 **1. 事务的概念** 事务是一系列操作的集合,这些操作要么全部成功,要么全部失败。在数据库系统中,事务处理确保了数据的一致性和完整性。Hibernate支持事务管理,提供了对事务的控制...
2. 事务隔离级别:Hibernate的版本管理机制与数据库的事务隔离级别相结合,可以实现不同级别的并发控制。例如,在可重复读(Repeatable Read)隔离级别下,虽然能防止脏读,但可能会出现幻读,此时版本管理机制可以...
### J2EE事务控制详解 ...通过选择合适的事务隔离级别,并结合乐观锁或悲观锁等策略,可以有效提高系统的并发性能和数据一致性。在实际应用中,开发者应根据业务需求和性能要求灵活选择最佳方案。
Hibernate支持四种标准的事务隔离级别,它们分别是READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ和SERIALIZABLE。不同的隔离级别会影响并发控制和脏读、不可重复读、幻读等问题。在Spring中,可以通过@...