我曾经在一个 Service 类中看到过一个标记为 @Transactional的方法,但是它也调用了同一个类中其他一些没有标记为 @Transactional的方法。
@Transactional
这是否意味着对单独方法的调用导致应用程序打开到 DB 的单独连接或挂起父事务等?
没有任何注释的方法的默认行为是什么,这是由另一个带有 @Transactional注释的方法调用的?
当您在事务块中调用一个没有 @Transactional的方法时,父事务将继续到新方法。它将使用来自父方法(使用 @Transactional)的相同连接,并且在被调用方法(不使用 @Transactional)中引起的任何异常都将导致事务按照事务定义中的配置回滚。
如果从属于同一 Spring Bean的 @Transactional方法中调用具有 @Transactional注释的方法,则所调用的方法事务行为将不会对事务产生任何影响。但是,如果从另一个具有事务定义的方法调用具有事务定义的方法,并且它们属于不同的 Spring Bean,那么被调用方法中的代码将遵循其自己的事务定义。
Bean
您可以在 春季交易文件春季交易文件的 声明性事务管理部分中找到更多的细节。
Spring 声明性事务模型使用 AOP 代理,因此 AOP 代理负责事务的创建。只有当被调用方法与调用方方法属于不同的 SpringBean时,AOP 代理才会处于活动状态。
@ Transactional 标记事务边界(开始/结束) ,但事务本身绑定到线程。一旦事务启动,它将在方法调用之间传播,直到原始方法返回并且事务提交/回滚。
如果调用了另一个具有@Transactional 注释的方法,则传播依赖于该注释的传播属性。
这取决于 传播水平。这里是所有可能的级别 价值观。
例如,在传播级别为 嵌套的情况下,当前事务将“挂起”,并创建一个新事务(注意: 嵌套事务的实际创建只能在特定的事务管理器上工作)
默认的传播级别(您称之为“行为”)是 需要。如果调用的“ inner”方法上有 @Transactional注释(或者通过 XML 以声明方式进行处理) ,那么它将在 同一笔交易中执行,例如,“ nothing new”被创建。
The inner method will affect the outer method if the inner method is not annotated with @Transactional.
如果内部方法也使用@Transactional 和 REQUIRES_NEW进行注释,那么将会发生以下情况。
REQUIRES_NEW
... @Autowired private TestDAO testDAO; @Autowired private SomeBean someBean; @Override @Transactional(propagation=Propagation.REQUIRED) public void outerMethod(User user) { testDAO.insertUser(user); try{ someBean.innerMethod(); } catch(RuntimeException e){ // handle exception } } @Override @Transactional(propagation=Propagation.REQUIRES_NEW) public void innerMethod() { throw new RuntimeException("Rollback this transaction!"); }
内部方法使用 REQUIRES_NEW进行注释,并抛出一个 RuntimeException,因此它将其事务设置为回滚,但不会影响外部事务。当内部事务启动时,外部事务为 PAUSED,然后在内部事务结束后为 RESUMES。它们彼此独立运行,因此外部事务可以成功提交。