Spring事务

Posted by Simon Dong on 2014-09-07

事务传播

Spring事务支持在TransactionDefinition中定义,有关事务的接口:

  • int getPropagationBehavior():事务的传播行为
  • int getIsolationLevel():事务的隔离级别
  • int getTimeout():事务过期时间
  • boolean isReadOnly(): 事务的读写属性

Spring具有7个事务传播行为:

传播行为 行为说明
PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行
PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED 类似的操作。

默认的事务传播行为是PROPAGATION_REQUIRED

多线程环境下的事务

当一个调用过程跨越线程时,由于Spring在大多数情况下是单例的,在这种情形下,Spring使用ThreadLocal将每个线程对数据库的连接进行无状态化,以实现Bean的单例的特性。
当一个多线程调用环境下,Spring的事务将仅限制在线程本身,无法实现跨线程的事务,结论是:在相同线程中进行的互相嵌套的事务方法工作于相同的事务中,如果这些相互嵌套的方法工作在不同的线程中时,不同的线程的事务方法工作在所属线程中独立的事务中。

混合数据访问的事务

各种不同的数据访问的事务管理器

DAO实现 JDBC技术 事务管理器
Hibernate Spring JDBC或iBatis HibernateTansactionManager
JPA Spring JDBC或iBatis JpaTransactionManager
JDO Spring JDBC或iBatis JdoTransactionManager

使用 Hibernate 事务管理器后,可以混合使用 Hibernate 和 Spring JDBC 数据访问技术,它们将工作于同一事务上下文中。但是使用 Spring JDBC 访问数据时,Hibernate 的一级或二级缓存得不到同步,此外,一级缓存延迟数据同步机制可能会覆盖 Spring JDBC 数据更改的结果。

如何直接获取数据源连接

不同的DAO框架获取数据源连接的工具类

DataSourceUtils 的等价类

DAO框架 连接获取工具类
Spring JDBC org.springframework.jdbc.datasource.DataSourceUtils
Hibernate org.springframework.orm.hibernate3.SessionFactoryUtils
iBatis org.springframework.jdbc.datasource.DataSourceUtils
JPA org.springframework.orm.jpa.EntityManagerFactoryUtils
JDO org.springframework.orm.jdo.PersistenceManagerFactoryUtils

TransactionAwareDataSourceProxy 的等价类

DAO框架 连接获取工具类
Spring JDBC org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
Hibernate org.springframework.orm.hibernate3.LocalSessionFactoryBean
iBatis org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
JPA
JDO org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy