`

Hibernate事物隔离级别[转]

 
阅读更多
事务不完全隔离会导致:脏读,不可重复读,幻读, 针对由事务的不完全隔离所引起的上述问题,提出了一些隔离级别,用来防范这些问题。
读操作未提交(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 事物隔离级别 深入探究

    10分钟解决Hibernate的事务管理,Hibernate当中要设置事务的隔离级别

    (3)隔离性:代表的是一个事务执行的过程当中,不应该受到其他事务的干扰。 (4)持久性:代表一个事务执行完成后数据就持久到数据库当中(提交或回滚)。 3、如果我们不考虑事务的隔离性,就会引发一些安全性的...

    Spring控制Hibernate中的事务传播特性与隔离级别操作.docx

    Spring控制Hibernate中的事务传播特性与隔离级别操作,通过利用spring和Hibernate的两个HibernateTemplate 和 jdbcTemplate类,实现数据的交互。

    hibernate初学者笔记

    关于hibernate的Session,向数据插入时的事务隔离级别,持久化对象的状态,对应关系的映射文件,表与表之间的多种映射关系,以及hibernate的二级缓存的笔记。

    Hibernate的Session_flush与隔离级别代码详解

    主要介绍了Hibernate的Session_flush与隔离级别代码详解,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

    Spring 事务隔离与事务传播的详解与对比

    Spring 事务隔离与事务传播的详解与对比 Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作。今天一起学习一下Spring的事务管理。Spring的事务管理分为声明式跟编程式。声明式就是在Spring的配置文件中...

    Spring + Hibernate + Struts

    比如说hibernate,我问一个同学session接口的get和load方法有何异同,这位...另外一个说精通spring,很多流行的词语,什么aop啊,什么声明性事务管理等等,我就问他spring里面事务的传播属性和事务隔离级别是怎么回事

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     21.3 数据库的事务隔离级别  21.3.1 在mysql.exe程序中设置隔离级别  21.3.2 在应用程序中设置隔离级别  21.4 在应用程序中采用悲观锁  21.4.1 利用数据库系统的独占锁来实现悲观锁  21.4.2 由应用程序实现...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     21.3 数据库的事务隔离级别  21.3.1 在mysql.exe程序中设置隔离级别  21.3.2 在应用程序中设置隔离级别  21.4 在应用程序中采用悲观锁  21.4.1 利用数据库系统的独占锁来实现悲观锁  21.4.2 由应用程序实现...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     21.3 数据库的事务隔离级别  21.3.1 在mysql.exe程序中设置隔离级别  21.3.2 在应用程序中设置隔离级别  21.4 在应用程序中采用悲观锁  21.4.1 利用数据库系统的独占锁来实现悲观锁  21.4.2 由应用程序实现...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     21.3 数据库的事务隔离级别  21.3.1 在mysql.exe程序中设置隔离级别  21.3.2 在应用程序中设置隔离级别  21.4 在应用程序中采用悲观锁  21.4.1 利用数据库系统的独占锁来实现悲观锁  21.4.2 由应用程序实现...

    hibernate 框架的基础四

    HQL的多表检索 事务及隔离级别 HQL优化 抓取策略

    Hibernate缓存管理

    doc格式。当多个并发的事务同时访问持久化层的缓存的相同数据时,会引起并发问题,必须采用必要的事务隔离措施。在进程范围或集群范围的缓存...因此可以设定四种类型的并发访问策略,每一种策略对应一种事务隔离级别。

    Java And 数据库事务

    事务,并发,隔离级别,JTA 事务,EJB,BMT,CMT,Spring,异常处理 异常处理还没有整理。 内容80%抄袭

    hibernate的flush()、refresh()、clear()针对一级缓存的操作的区别.docx

    首先session是有一级缓存的,目的是为了减少查询数据库的时间,提高效率,一级缓存的生命周期和session是一样的, session.flush()和session.clear...该方法的有效性需要配置事务的隔离级别为read commited(读已提交)。

    尚硅谷佟刚Spring4代码及PPT.rar

    JdbcDaoSupport、使用 NamedParameterJdbcTemplate、Spring 的声明式事务、事务的属性(传播行为、隔离级别、回滚属性、只读属性、过期时间)、使用 XML 文件的方式配置事务、整合 Hibernate、整合 Struts2 等。

    spring考试通过必备材料.docx

    事务的隔离级别设置为DEFALIT 26 在applicationContext.xml中配置文件通知 27 JDBC 28 Text测试类 29 Hibernate.cfg.xml 31 AOP方法的通知 31 单独前置通知 31 单独后置通知 32 单独环绕通知 32

    spring.doc

    5.1.8.3Spring事务的隔离级别 117 拓展: 118 5.1.8.4以XML配置的 形式 119 拓展: 120 5.1.8.5以注解方式配置 125 拓展: 127 5.1.9使用CGLIB以XML形式配置事务 130 5.2 Spring+Hibernate 131 5.2.1 ...

Global site tag (gtag.js) - Google Analytics