问题描述
与方法之间有什么区别
@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(){
}
}
1楼
除了关于同步的指示上的细微差别外,两者之间的区别是,如果方法使用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。
2楼
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 。 您可以在找到文档。