读书人

Spring 宣言式事务

发布时间: 2013-09-17 13:35:59 作者: rapoo

Spring 声明式事务

基于@Transactional注解的事务方式

?

首先配置Spring容器:

?

?配置中的<tx:annotation-driven/>属性proxy-target-class决定为那些使用了@Transactional注解的类创建何种事务代理。 如果 "proxy-target-class" 属性被设为 "true", 那么基于类的代理就会被创建。即使用CGLib创建增强的代理,如果 "proxy-target-class"属性被设为"false" 或者没设,那么基于接口的标准JDK代理就会被创建。

?

@Transactional注解可以被应用于接口定义和接口方法、类定义和类的?public?方法上。 然而,请注意只是使用@Transactional注解并不会启用事务行为, 它仅仅?是一种元数据,能够被可以识别@Transactional注解和上述的配置适当的具有事务行为的beans所使用。其实是<tx:annotation-driven/>元素的出现?开启了事务行为。

Spring团队的建议是你只在具体的类上使用@Transactional注解, 而不要注解在接口上。我在实际项目中一般只在操作数据库的方法上使用,而不是在整个类上使用。

?

属性类型描述propagation枚举型:Propagation可选的传播性设置isolation枚举型:Isolation可选的隔离性级别(默认值:ISOLATION_DEFAULT)readOnly布尔型读写型事务 vs. 只读型事务timeoutint型(以秒为单位)事务超时rollbackFor一组Class类的实例,必须是Throwable的子类一组异常类,遇到时?必须?进行回滚。默认情况下checked exceptions不进行回滚,仅unchecked exceptions(即RuntimeException的子类)才进行事务回滚。rollbackForClassname一组Class类的名字,必须是Throwable的子类一组异常类名,遇到时?必须?进行回滚noRollbackFor一组Class类的实例,必须是Throwable的子类一组异常类,遇到时?必须不?回滚。noRollbackForClassname一组Class类的名字,必须是Throwable的子类一组异常类,遇到时?必须不?回滚

事务传播行为

Spring管理的事务是逻辑事务,而且物理事务和逻辑事务最大差别就在于事务传播行为,事务传播行为用于指定在多个事务方法间调用时,事务是如何在这些方法间传播的,Spring共支持7种传播行为:

Required:默认的事务传播行为,表示必须有逻辑事务,否则新建一个事务,使用PROPAGATION_REQUIRED指定,表示如果当前存在一个逻辑事务,则加入该逻辑事务,否则将新建一个逻辑事务:

Spring 宣言式事务

RequiresNew:创建新的逻辑事务,使用PROPAGATION_REQUIRES_NEW指定,表示每次都创建新的逻辑事务(物理事务也是不同的)因此外部事务可以不受内部事务回滚状态的影响独立提交或者回滚。

Spring 宣言式事务

Supports:支持当前事务,使用PROPAGATION_SUPPORTS指定,指如果当前存在逻辑事务,就加入到该逻辑事务,如果当前没有逻辑事务,就以非事务方式执行。

NotSupported:不支持事务,如果当前存在事务则暂停该事务,使用PROPAGATION_NOT_SUPPORTED指定,即以非事务方式执行,如果当前存在逻辑事务,就把当前事务暂停,以非事务方式执行。

Mandatory:使用PROPAGATION_MANDATORY指定,如果当前有事务,使用当前事务执行,如果当前没有事务,则抛出异常(IllegalTransactionStateException)。

Never:不支持事务,如果当前存在是事务则抛出IllegalTransactionStateException异常,使用PROPAGATION_NEVER指定。

?

Nested:嵌套事务支持,使用PROPAGATION_NESTED指定,如果当前存在事务,则在嵌套事务内执行,如果当前不存在事务,则创建一个新的事务,嵌套事务使用数据库中的保存点来实现,即嵌套事务回滚不影响外部事务,但外部事务回滚将导致嵌套事务回滚。

Nested和RequiresNew的区别:?

  • RequiresNew每次都创建新的独立的物理事务,而Nested只有一个物理事务;
  • Nested嵌套事务回滚或提交不会导致外部事务回滚或提交,但外部事务回滚将导致嵌套事务回滚,而 RequiresNew由于都是全新的事务,所以之间是无关联的;
  • Nested使用JDBC 3的保存点实现,即如果使用低版本驱动将导致不支持嵌套事务。

    ? ? 实际应用中一般使用默认的事务传播行为,偶尔会用到RequiresNew和Nested方式。

    基于XML配置的事务

    个人比较偏爱使用@Transactional注解的方式,但是很大一部分项目是使用XML方式的,使用XML方式只需要把上面配置中的

    ?去掉,然后添加如下配置即可:

     

读书人网 >编程

热点推荐