Spring事务本质是对数据库事务的支持,如果数据库不支持事务(例如MySQL的MyISAM引擎不支持事务),则Spring事务也不会生效。

Spring的事务传播

事务传播行为是指一个事务方法A被另一个事务方法B调用时,这个事务A应该如何处理。事务A应该在事务B中运行还是另起一个事务,这个有事务A的传播行为决定。
事务传播属性定义TransactionDefinition

  1. int PROPAGATION_REQUIRED = 0;
  2. int PROPAGATION_SUPPORTS = 1;
  3. int PROPAGATION_MANDATORY = 2;
  4. int PROPAGATION_REQUIRES_NEW = 3;
  5. int PROPAGATION_NOT_SUPPORTED = 4;
  6. int PROPAGATION_NEVER = 5;
  7. int PROPAGATION_NESTED = 6;
常量名称 常量解释
PROPAGATION_REQUIRED 支持当前事务,如果当前没有事务,就新建一个事务。这是Spring 默认的事务的传播。
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行
PROPAGATION_MANDATORY 支持当前事务,如果当前没有事务,就抛出异常
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。新建的事务将和被挂起的事务没有任何关系,是两个独立的事务,外层事务失败回滚之后, 不能回滚内层事务执行的结果,内层事务失败抛出异常,外层事务捕获, 也可以不处理回滚操作。 使用JtaTransactionManager作为事务管理器
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。使用JtaTransactionManager作为事务管理器
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。

PROPAGATION_REQUIRED

如果存在一个事务,则支持当前事务,如果没有事务则开启事务
image.png

PROPAGATION_SUPPORTS

如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。
image.png

PROPAGATION_MANDATORY

如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
image.png

PROPAGATION_REQUIRES_NEW

使用PROPAGATION_REQUIRES_NEW,需要使用 JtaTransactionManager作为事务管理器。
它会开启一个新的事务。如果一个事务已经存在,则先将这个存在的事务挂起。
image.png

PROPAGATION_NOT_SUPPORTED

总是非事务地执行,并挂起任何存在的事务。
使用PROPAGATION_NOT_SUPPORTED,也需要使用JtaTransactionManager作为事务管理器。
image.png

PROPAGATION_NEVER

总是非事务地执行,如果存在一个活动事务,则抛出异常。

PROPAGATION_NESTED

如果一个活动的事务存在,则运行在一个嵌套的事务中。
如果没有活动事务,则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。
这是一个嵌套事务,使用JDBC3.0驱动时,仅仅支持DataSourceTransactionManager作为事务管理器。 需要JDBC 驱动的java.sql.Savepoint类。使用PROPAGATION_NESTED,还需要把PlatformTransactionManager的nestedTransactionAllowed属性设为true(属性值默认为false)。
image.png

Spring事务的隔离级别

事务隔离级别定义TransactionDefinition

  1. int ISOLATION_DEFAULT = -1;
  2. int ISOLATION_READ_UNCOMMITTED = 1;
  3. int ISOLATION_READ_COMMITTED = 2;
  4. int ISOLATION_REPEATABLE_READ = 4;
  5. int ISOLATION_SERIALIZABLE = 8;
隔离级别 解释
ISOLATION_DEFAULT 这是个 PlatfromTransactionManager 默认的隔离级别, 使用数据库默认的事务隔离级别。另外四个与 JDBC 的 隔离级别相对应。
ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它允许另外一个事务可以看 到这个事务未提交的数据。这种隔离级别会产生脏读, 不可重复读和幻像读。
ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读 取。另外一个事务不能读取该事务未提交的数据。 ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被 处理为顺序执行

Spring事务基本配置样例

  1. <aop:aspectj-autoproxy proxy-target-class="true"/>
  2. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  3. <property name="dataSource" ref="dataSource"/>
  4. </bean>
  5. <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
  6. <tx:attributes>
  7. <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
  8. <tx:method name="remove*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
  9. <tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception,RuntimeException,SQLException"/>
  10. <tx:method name="login" propagation="NOT_SUPPORTED"/>
  11. <tx:method name="query*" read-only="true"/>
  12. </tx:attributes>
  13. </tx:advice>
  14. <aop:config>
  15. <aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionPointcut"/>
  16. <aop:aspect ref="dataSource">
  17. <aop:pointcut id="transactionPointcut" expression="execution(public * com.gupaoedu..*.service..*Service.*(..))" />
  18. </aop:aspect>
  19. </aop:config>