本教程将仅关注事务的传播机制行为。Spring事务的其他方面的细节,你可以参考其他的教程或Spring官方文档。
本教程所使用的完整代码可以在教程的下方下载。我们将仅显示Spring中帮助大家了解事务传播机制相关部分。
完整的源代码使用Hibernate实现持久层(Spring使用Hibernate的事务示例)。
Spring的REQUIRED行为意味着如果在当前bean方法执行的上下文中已存在打开的事务,则使用该事务;如果没有已存在的事务,则Spring容器会创建新的事务并使用它。如果多个方法均配置为REQUIRED且调用为嵌套调用,那么它们会被划分为多个逻辑的事务,但在底层使用相同物理事务。简单来说,这意味着如果内层的方法引起了事务回滚,则外部的方法调用事务也会失败同时回滚。让我们看看一个示例:
@Autowired private TestDAO testDAO; @Autowired private InnerBean innerBean; @Override @Transactional(propagation=Propagation.REQUIRED) public void testRequired(User user) { testDAO.insertUser(user); try{ innerBean.testRequired(); } catch(RuntimeException e){ // handle exception } }
@Override @Transactional(propagation=Propagation.REQUIRED) public void testRequired() { throw new RuntimeException("Rollback this transaction!"); }
注意内部bean的方法使用了REQUIRED进行了注解并抛出了RuntimeException。这意味着它将于外部bean使用相同的事务,因此外部事务在提交时将失败并同样进行回滚操作。
注意:默认情况下,只有非受检异常(unchecked exception),像RuntimeException,会将事务的状态设置为回滚。如果你希望受检异常(checked exception)也可以将事务状态设置为回滚,你必须设置它们,但此内部不包含在本教程中。
注意2:当使用声明式事务时(也就是通过使用注解形式),如果在相同的bean中直接调用方法(自己调用自己的方法),@Transactional注解将被容器忽略。如果你希望启用自身方法调用的事务管理,你必须使用aspectj来配置事务,但是该内容不包含在本教程中。
REQUIRES_NEW行为意味着容器将总会创建新的物理的事务。换句话说,内部的事务可以独立于外部事务而提交或回滚事务,也就是说外部的事务将不受内部事务的结果影响:它们将返回不同的物理事务。.
@Autowired private TestDAO testDAO; @Autowired private InnerBean innerBean; @Override @Transactional(propagation=Propagation.REQUIRED) public void testRequiresNew(User user) { testDAO.insertUser(user); try{ innerBean.testRequiresNew(); } catch(RuntimeException e){ // handle exception } }
@Override @Transactional(propagation=Propagation.REQUIRES_NEW) public void testRequiresNew() { throw new RuntimeException("Rollback this transaction!"); }内部方法使用REQUIREDS_NEW进行注解,并抛出RuntimeException,因此它的事务会回滚但是不会影响到外部的事务。外部事务在内部事务启动时将被挂起然后在内部事务处理完毕后恢复。它们独立的进行处理因此外部的事务也会成功的提交。
NESTED行为使用相同的物理事务但是在嵌套调用时设置了保留点(savepoint),因此内部的事务可以独立于外部事务回滚而不影响外部事务。这个可能与JDBC的savepoint比较类似,因此该行为需要与Spring的JDBC管理的事务一起使用(Spring JDBC 事务例子).
NEVER行为要求执行该方法时,不能有已存在的事务。如果事务已存在,那么容器将会抛出异常。
NOT_SUPPORTED行为标示在执行方法时,将忽略事务。如果已存在打开的事务,则该事务会被挂起。
SUPPORTS行为标示在执行方法时,如果存在事务,则在事务范围执行,如果不存在,则不以事务方式执行。
本页尾有完整的代码下载。下面是 MySQL 建表语句:
CREATE TABLE USER ( ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, USERNAME VARCHAR (32) NOT NULL, NAME VARCHAR (64) NOT NULL, UNIQUE (USERNAME) );
评论删除后,数据将无法恢复
评论(0)