@Transactional 方法在没有 @Transactional 注解的情况下调用另一个方法?
我在 Service 类中看到了一个标记为 @Transactional
的方法,但它还调用了同一类中未标记为 @Transactional
的其他一些方法。
这是否意味着对单独方法的调用导致应用程序打开与数据库的单独连接或挂起父事务等?
没有任何注释的方法被另一个带有 @Transactional 注释的方法调用的默认行为是什么?
I've seen a method in a Service class that was marked as @Transactional
, but it was also calling some other methods in that same class which were not marked as @Transactional
.
Does it mean that the call to separate methods are causing the application to open separate connections to DB or suspend the parent transaction, etc?
What's the default behavior for a method without any annotations which is called by another method with @Transactional
annotation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您在事务块内调用没有
@Transactional
的方法时,父事务将传播到新方法。它将使用来自父方法的相同连接(带@Transactional
),并且在被调用方法(不带@Transactional
)中引起的任何异常都将导致事务按配置回滚在交易定义中。如果您从属于同一个 Spring Bean 的带有
@Transactional
的方法调用带有@Transactional
注解的方法,那么被调用方法的事务行为不会对该方法产生任何影响。交易。但是,如果您从另一个具有事务定义的方法调用一个具有事务定义的方法,并且它们属于不同的 Spring Bean,那么被调用方法中的代码将遵循其自己的事务定义。您可以在 Spring 事务管理文档。
Spring声明式事务模型使用AOP代理,因此AOP代理负责事务的创建。仅当被调用方法属于与调用方不同的 Spring
Bean
时,AOP 代理才会处于活动状态。When you call a method without
@Transactional
within a transaction block, the parent transaction will propagate to the new method. It will use the same connection from the parent method (with@Transactional
) and any exception caused in the called method (without@Transactional
) will cause the transaction to rollback as configured in the transaction definition.If you call a method with a
@Transactional
annotation from a method with@Transactional
belonging to the same Spring Bean, then the called method's transactional behavior will not have any impact on the transaction. But if you call a method with a transaction definition from another method with a transaction definition, and they belong to different Spring Beans, then the code in the called method will follow its own transaction definitions.You can find more details in the section Declarative transaction management of Spring Transaction Management documentation.
Spring declarative transaction model uses an AOP proxy, so the AOP proxy is responsible for the creation of the transactions. The AOP proxy will be active only if the called method belongs to a different Spring
Bean
than the caller one.这取决于 传播级别。以下是所有可能的级别 价值观。
例如,如果传播级别为 NESTED 当前事务将“挂起”并创建一个新事务(注意:实际创建嵌套事务仅适用于特定事务管理器)
默认的传播级别(您所说的“行为”)是 必需。如果调用带有
@Transactional
注释的“内部”方法(或通过 XML 进行声明式事务),它将在同一事务中执行,例如“无新的”被创建。That depends on a propagation level. Here are all the possible level values.
For example in case a propagation level is NESTED a current transaction will "suspend" and a new transaction will be created ( note: actual creation of a nested transaction will only work on specific transaction managers )
The default propagation level ( what you call "behavior" ) is REQUIRED. In case an "inner" method is called that has a
@Transactional
annotation on it ( or transacted declaratively via XML ), it will execute within the same transaction, e.g. "nothing new" is created.@Transactional
标记事务边界(开始/结束),但事务本身是绑定到线程的。一旦事务开始,它就会在方法调用之间传播,直到原始方法返回并且事务提交/回滚。如果调用另一个具有 @Transactional 注释的方法,则传播取决于该注释的传播属性。
@Transactional
marks the transaction boundary (begin/end), but the transaction itself is bound to the thread. Once a transaction starts, it propagates across method calls until the original method returns and the transaction commits/rolls back.If another method is called that has a
@Transactional
annotation, then the propagation depends on the propagation attribute of that annotation.如果内部方法没有使用
@Transactional
注解,内部方法将会影响外部方法。如果内部方法也使用
@Transactional
和Propagation.REQUIRES_NEW
进行注释,则会发生以下情况。内部方法用
REQUIRES_NEW
注释并抛出RuntimeException
,因此它将设置其事务回滚,但不会影响外部事务。当内部事务开始时,外部事务暂停,然后在内部事务结束后恢复。它们彼此独立运行,因此外部事务可能会成功提交。The inner method will affect the outer method if the inner method is not annotated with
@Transactional
.In case the inner method is also annotated with
@Transactional
withPropagation.REQUIRES_NEW
, the following will happen.The inner method is annotated with
REQUIRES_NEW
and throws aRuntimeException
, so it will set its transaction to rollback but WILL NOT EFFECT the outer transaction. The outer transaction is PAUSED when the inner transaction starts and then RESUMES AFTER the inner transaction is concluded. They run independently of each other, so the outer transaction MAY commit successfully.