事务->ACID
1.Atomic原子性 【(各个操作不可分割)一个逻辑单元 】
2.Consistency一致性 【 回滚rollback;合法 】
3.Isolation隔离性 【 不能看到其他事务正在修改的数据(看到改之前或者该之后的数据)】
Hibernate中的事务隔离依赖于底层数据库提供的事务隔离机制,因此对数据库事务隔离机制的理解在基于Hibernate实现的持久层中同样适用。
数据操作过程中可能出现的3种不确定情况:
1)Dirty Reads 【 读取其他事务未提交的数据 】
2)Non-repeatable Reads 【 操作过程中两次读取的数据不一致(中间被某已提交事务修改) 】
3)Phantom Reads虚读 【 一个事务重新执行一个查询,返回一套符合查询条件的记录,但这些记录中包含了因为其他最近提交的事务而产生的新记录。】
标准SQL规范中,定义了如下4个事务隔离等级:
1)Read Uncommitted
最低等级的事务隔离,它仅仅保证了读取过程中不会读取到非法数据。这种隔离等级下,上述3种不确定情况均有可能发生。
2)Read Committed
此级别的事务隔离保证了一个事务不会读到另一个并行事务已修改但未提交的数据,也就是说,此等级的事务级别避免了“脏读取”。
永远无法看到未提交的数据
大多数主流数据库的默认事务等级,同时也适用于大多数系统。
3)Repeatable Read
此级别的事务隔离避免了“脏读取”和“不可重复读取”现象的出现。这也意味着,一个事务不可能更新已经由另一个事务读取但未提交(回滚)的数据。
一般而言,此级事务应用并不广泛,它并不能完全保证数据的合法性(可能出现虚读)。同时也带来了更多的性能损失,如果当前数据库由应用所独享,那么可以考虑通过“乐观锁”达到同样的目的。
4)Serializable【 串行执行 】
4.Durability持久性 【 固化 】
Hibernate是JDBC的轻量级封装,本身并不具备事务管理能力,在事务管理层,Hibernate将其委托给底层的JDBC或者JTA,以实现事务的管理和调度。
Hibernate的默认事务处理机制基于JDBC Transaction。我们也可以通过配置文件设定采用JTA作为事务管理实现:
<hibernate-configuration> <session-factory> … <property name=”hibernate.transation.factory_class”> net.sf.hibernate.transaction.JTATransactionFactory <!—net.sf.hibernate.transaction.JDBCTransactionFactory--> </property> … </session-factory> </hibernate-configuration>
1)基于JDBC的事务管理
Hibernate对于JDBC事务的封装也非常简单。
看下面这段代码:
session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); … tx.commit();
从JDBC层面而言,上面的代码实际上对应着:
Connection dbconn = getConnection(); dbconn.setAutoCommit(false); … dbconn.commit();
注:在sessionFactory.openSession()中,Hibernate会初始化数据库连接,与此同时,将其AutoCommit设置为关闭状态(false)。而其后,在session.beginTransaction方法中,Hibernate会再次确认Connection的AutoCommit属性被设为关闭状态(为了防止用户代码对session的Connection.AutoCommit属性进行修改)。
这也就是说,我们一开始从sessionFactory获得的session,其自动提交属性就已经被关闭(AutoCommit=false)
如果要使代码真正作用到数据库,必须显示地调用Transaction指令。
2) 基于JTA的事务管理
JTA提供了跨Session的事务管理能力,这一点是与JDBC Transaction最大的差异。
JDBC事务由Connection管理,也就是说,事务管理实际上是在JDBC Connection中实现。事务周期限于Connection的生命周期之内。
JTA事务管理则由JTA容器实现,JTA容器对当前加入事务的众多Connection进行调度,实现其事务性要求。JTA的事务周期可横跨多个JDBC Connection生命周期。同样对于基于JTA事务的Hibernate而言,JTA事务横跨可横跨多个session。
注:参与JTA事务的Connection需避免对事务管理进行干涉。这也就是说,如果采用JTA Transaction,我们不应该再调用Hibernate的Transaction功能。
在EJB中使用JTA Transaction无疑最为简便,我们只需要将save方法配置为JTA事务支持即可,无需显式声明任何事务.