事务不完全隔离会导致:脏读,不可重复读,幻读, 针对由事务的不完全隔离所引起的上述问题,提出了一些隔离级别,用来防范这些问题。
读操作未提交(Read Uncommitted): 说明一个事务在提交前,其变化对于其他事务来说是可见的。这样脏读、不可重读和幻读都是允许的。当一个事务已经写入一行数据但未提交,其他事务都不能再写入此行数据;但是,任何事务都可以读任何数据。这个隔离级别使用排写锁实现。
读操作已提交(Read Committed): 读取未提交的数据是不允许的,它使用临时的共读锁和排写锁实现。这种隔离级别不允许脏读,但不可重读和幻读是允许的。
可重读(Repeatable Read): 说明事务保证能够再次读取相同的数据而不会失败。此隔离级别不允许脏读和不可重读,但幻读会出现。 可串行化(Serializable): 提供最严格的事务隔离。这个隔离级别不允许事务并行执行,只允许串行执行。这样,脏读、不可重读或幻读都可发生。 事务隔离与隔离级别的关系如表9-2所示。 表9-2 事务隔离与隔离级别的关系
隔离级别 脏读(Dirty Read) 不可重复读(Unrepeatable Read) 幻读(Phantom Read) 读操作未提交 (Read Uncommitted) 可能 可能 可能
读操作已提交 (Read Committed) 不可能 可能 可能
可重读 (Repeatable Read) 不可能 不可能 可能
可串行化 (Serializable) 不可能 不可能 不可能
在一个实际应用中,开发者经常不能确定使用什么样的隔离级别。太严厉的级别将降低并发事务的性能,但是不足够的隔离级别又会产生一些小的Bug ,而这些Bug 只会在系统重负荷(也就是并发严重时)的情况下才会出现。
一般来说,读操作未提交(Read Uncommitted)是很危险的。一个事务的回滚或失败都会影响到另一个并行的事务,或者说在内存中留下和数据库中不一致的数据。这些数据可能会被另一个事务读取并提交到数据库中。这是完全不允许的。
另外,大部分程序并不需要可串行化隔离(Serializable Isolation)。虽然,它不允许幻读,但一般来说,幻读并不是一个大问题。可串行化隔离需要很大的系统开支,很少有人在实际开发中使用这种事务隔离模式。 现在留下来的可选的隔离级别是读操作已提交(Read Committed)和可重读(Repeatable Read)。
Hibernate 可以很好地支持可重读(Repeatable Read)隔离级别。 在Hibernate配置文件中设置隔离级别 JDBC连接数据库使用的是默认隔离级别,即读操作已提交(Read Committed)和可重读(Repeatable Read)。
在Hibernate的配置文件hibernate.properties中,可以修改隔离级别: #hibernate.connection.isolation 4
在上一行代码中,Hibernate事务的隔离级别是4,这是什么意思呢?级别的数字意义如下。 1:读操作未提交(Read Uncommitted)
2:读操作已提交(Read Committed)
4:可重读(Repeatable Read)
8:可串行化(Serializable)
因此,数字4表示“可重读”隔离级别。如果要使以上语句有效,应把此语句行前的注释符“#”去掉: hibernate.connection.isolation 4 也可以在配置文件hibernate.cfg.xml 中加入以下代码:
<session-factory> ….. // 把隔离级别设置为4
<property name=” hibernate.connection.isolation”>4</property> …… </session-factory>
在开始一个事务之前,Hibernate 从配置文件中获得隔离级别的值。
在Hibernate中使用JDBC事务 Hibernate对JDBC进行了轻量级的封装,它本身在设计时并不具备事务处理功能。Hibernate将底层的JDBCTransaction或JTATransaction进行了封装,再在外面套上Transaction和Session的外壳,其实是通过委托底层的JDBC或JTA来实现事务的处理功能的。 要在Hibernate中使用事务,可以在它的配置文件中指定使用JDBCTransaction或者JTATransaction 。
在hibernate.properties中,查找“transaction.factory_class”关键字,得到以下配置:
# hibernate.transaction.factory_class org.hibernate.transaction.JTATransactionFactory # hibernate.transaction.factory_class org.hibernate.transaction.JDBCTransactionFactory Hibernate的事务工厂类可以设置成JDBCTransactionFactory或者JTATransactionFactory。如果不进行配置,Hibernate就会认为系统使用的事务是JDBC事务。
在JDBC的提交模式(commit mode)中,如果数据库连接是自动提交模式(auto commit mode),那么在每一条SQL语句执行后事务都将被提交,提交后如果还有任务,那么一个新的事务又开始了。 Hibernate在Session控制下,在取得数据库连接后,就立刻取消自动提交模式,即Hibernate在一个执行Session 的beginTransaction()方法后,就自动调用JDBC层的setAutoCommit(false)。如果想自己提供数据库连接并使用自己的SQL语句,为了实现事务,那么一开始就要把自动提交关掉(setAutoCommit(false)),并在事务结束时提交事务。 使用JDBC事务是进行事务管理最简单的实现方式,Hibernate对于JDBC事务的封装也很简单。
下面是一个在Hibernate中使用JDBC事务的例子:
try {
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction(); // 在默认情况下,开启一个JDBC 事物
for(int i=0; i<10; i++) {
Student stu = new Student(); stu.setName("Student" + i); session.save(stu);
}
tx.commit(); // 提交事务
session.close();
} catch(Exception e) {… tx.rollback(); // 事务回滚 }
在Hibernate中使用JTA事务 JTA(Java Transaction API)是事务服务的J2EE解决方案。本质上,它是描述事务接口的J2EE模型的一部分,开发人员直接使用该接口或者通过J2EE容器使用该接口来确保业务逻辑能够可靠地运行。
JTA有3个接口,它们分别是UserTransaction接口、TransactionManager接口和Transaction接口。这些接口共享公共的事物操作,例如commit()和rollback(),但也包含特殊的事务操作,例如suspend()、resume()和enlist(),它们只出现在特定的接口上,以便在实现中允许一定程度的访问控制。 在一个具有多个数据库的系统中,可能一个程序会调用几个数据库中的数据,需要一种分布式事务,或者准备用JTA来管理跨Session的长事务,那么就需要使用JTA事务。下面介绍如何在Hibernate的配置文件中配置JTA 事务。在hibernate.properties文件中设置如下(把JTATransactionFactory所在的配置行的注释符“#”取消掉): hibernate.transaction.factory_class org.hibernate.transaction.JTATransactionFactory # hibernate.transaction.factory_class org.hibernate.transaction.JDBCTransactionFactory 或者在hibernate.cfg.xml 文件中配置如下:
<session-factory>
…
<property name=” hibernate.transaction.factory_class”> org.hibernate.transaction.JTATransactionFactory </property>
……
</session-factory>
下面是一个应用JTA 事务的例子:
javax.transaction.UserTransaction tx = null;
tx = new initialContext().lookup(” javax.transaction.UserTransaction ”) ;
tx.begin();
Session s1 = sf.openSession();
……
s1.flush();
s1.close();
Session s2 = sf.openSession();
……
s2.flush();
s2.close();
tx.commit();
分享到:
相关推荐
Hibernate 事务隔离级别 深入探究 在 Hibernate 中,事务隔离级别是指数据库系统提供的一种机制,以解决并发事务带来的问题。为了确保数据库的可靠性和一致性,Hibernate 提供了四种事务隔离级别,分别是 ...
本文主要关注于使用Hibernate进行事务管理和设置事务隔离级别的知识。Hibernate是一个流行的Java ORM(对象关系映射)框架,它简化了数据库操作,同时也提供了对事务的管理。 首先,我们需要理解事务的基本概念。...
Hibernate还允许开发者通过配置设置不同的事务隔离级别,以满足不同应用场景下的需求。常见的隔离级别包括: - `READ_UNCOMMITTED` - `READ_COMMITTED` - `REPEATABLE_READ` - `SERIALIZABLE` 这些级别的选择取决...
根据数据库系统的不同,Hibernate支持四种事务隔离级别:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。不同的隔离级别会带来不同的并发控制效果,开发者需要根据实际需求选择合适的级别。 ##...
- 注解驱动:使用`@Transactional`注解直接在服务层的方法上,指定事务属性,如传播行为、隔离级别、超时和是否只读。 2. **传播行为:**决定了事务如何在不同的调用之间传播。例如,`PROPAGATION_REQUIRED`是最...
例如,对于读多写少的场景,乐观锁和较高的事务隔离级别(如Repeatable Read)可能是更好的选择。而对于写操作频繁的情况,悲观锁和更低的隔离级别可能更合适。 总的来说,理解并熟练掌握Hibernate的事务和并发控制...
在Spring框架中,为了管理和控制Hibernate事务,Spring提供了两种关键工具:HibernateTemplate和JdbcTemplate。这两个模板类简化了与数据库的交互,同时也处理了事务管理。让我们深入了解一下这两个类以及它们如何...
Hibernate提供了四种事务隔离级别:读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE)。开发者可以根据应用场景选择合适的隔离级别。此外,...
这个注解可以应用在类或方法级别,用于指定事务的传播行为、隔离级别、超时限制以及是否回滚默认异常。例如: ```java @Service @Transactional(isolation = Isolation.REPEATABLE_READ) public class UserService ...
在需要进行事务处理的业务层方法上添加@Transactional注解,指定事务属性如传播行为、隔离级别、读写模式等。例如: ```java @Service public class UserService { @Transactional public void addUser(User ...
这个注解允许我们指定事务的传播行为(如REQUIRED、REQUIRES_NEW等)、隔离级别(如READ_COMMITTED、SERIALIZABLE等)以及回滚规则。这种方式使得事务管理变得简单且易于维护。 对于源码分析,Spring的`...
这意味着,当你的应用程序与数据库进行交互时,其行为遵循数据库定义的事务隔离级别,而真正的事务支持取决于底层数据库的实现。 #### 三、事务并发处理 Hibernate 提供了两种主要的并发控制机制: 1. **乐观锁...
Hibernate支持四种事务隔离级别,对应SQL标准的四种隔离级别: - READ UNCOMMITTED:读未提交 - READ COMMITTED:读已提交 - REPEATABLE READ:可重复读 - SERIALIZABLE:串行化 五、编程式事务管理 在代码中...
- 在Service层的方法上添加@Transactional注解,指定事务的传播行为(如REQUIRED、REQUIRES_NEW等)和隔离级别。 - 在DAO层,使用Hibernate的Session和Query对象进行数据库操作,Spring会在事务的上下文中管理这些...
在Hibernate的配置文件中,可以设置事务相关的属性,比如默认的事务隔离级别、是否自动开始事务等。例如: ```xml <property name="hibernate.connection.isolation">2</property> <!-- 2对应READ_COMMITTED隔离...
在Spring中,你可以为特定的类或方法声明事务属性,如事务的传播行为、隔离级别、是否回滚等。这些配置通常在Spring的XML配置文件中完成,或者使用Java配置类进行。当一个方法被标记为@Transactional,Spring会在...
Hibernate支持的事务隔离级别与JDBC相同,可以通过配置`hibernate.connection.isolation`属性进行设置。 ### 3. 事务的并发处理 在多用户环境中,事务的并发处理至关重要。常见的并发问题包括: - **脏读(Dirty ...
在 Hibernate 中,可以通过设置 hibernate.connection.isolation 属性来指定事务隔离级别。 例如: ```xml <property name="hibernate.connection.isolation">2 ``` 这将设置事务隔离级别为 READ_COMMITTED。 解决...
Spring事务管理器会自动处理事务的开始、提交、回滚,并根据方法的配置自动调整事务隔离级别。 总结,Hibernate的事务管理是保证数据库操作正确性和一致性的关键,理解并熟练运用事务的四大特性及不同隔离级别,能...