方法与
有什么区别@Transactional(propagation = Propagation.SUPPORTS)
和没有@Transactional
的方法?
例如:
public class TEst {
@Transactional
public void methodWithTransaction1(){
methodWithSupportsTransaction();
}
@Transactional
public void methodWithTransaction2(){
methodWithoutTransactional();
}
@Transactional(propagation = Propagation.SUPPORTS)
public void methodWithSupportsTransaction(){
}
public void methodWithoutTransactional(){
}
}
答案 0 :(得分:3)
除the javadoc中有关同步的细微差别外,两者之间的区别在于,如果方法使用Transactional注释,则事务代理会截取方法调用,并将当前事务(如果有)标记为rollbackOnly如果从该方法抛出运行时异常。
所以,让我们举一个例子:
public class A {
@Autowired B b;
@Transactional
public void foo() {
try {
b.bar();
}
catch (RuntimeException e) {
// ignore
}
...
}
}
public class B {
// @Transactional(propagation = Propagation.SUPPORTS)
public void bar() {
throw new RuntimeException();
}
}
如果尚未存在,则调用a.foo()
将启动事务(传播必需)。然后将调用b.bar()并抛出异常。 a.foo()
捕获了异常,它继续执行,好像什么都没发生一样。在a.foo()
结束时,交易将成功提交。
现在让我们取消注释b.bar()
上的Transactional注释。如果尚不存在,则调用a.foo()
将启动事务(传播必需)。然后将调用b.bar()并抛出异常。此异常将由B周围的事务代理“拦截”,这将事务标记为rollbackOnly。然后异常将传播到A. a.foo()
。 a.foo()
捕获了异常,它继续执行,好像什么都没发生一样。在a.foo()
结束时,事务将被提交,但该提交将失败,因为事务已被标记为rollbackOnly。 a.foo()的调用者将获得TransactionSystemException。
答案 1 :(得分:0)
Spring支持两种类型的事务管理程序化和声明性。
程序化交易管理:以这种方式,交易需要由我们处理。例如 -
EntityTransaction tran = entityManager.getTransaction();
try {
tran.begin();
methodWithoutTransactional();
tran.commit();
} catch(Exception ex) {
tran.rollback();
throw ex;
}
声明式事务管理:通过这种方式,我们可以简单地通过使用注释或基于xml的配置将事务管理代码与业务逻辑分离出来。你已经在示例代码中完成了哪些 -
@Transactional
public void methodWithTransaction1(){
methodWithSupportsTransaction();
}
对于 @Transactional 注释,如果我们不定义传播类型,默认情况下将应用 PROPAGATION_REQUIRED 。您可以找到文档here。