Spring 中的声明式事务管理行为不可预测

发布于 2024-12-02 10:21:08 字数 1033 浏览 0 评论 0原文

我有一个带有声明式事务管理的 Spring+Hibernate 应用程序。 我有一个服务 (FooService),它有 2 个公共方法 MethodAMethodB。客户端将调用MethodA,而MethodA又将调用MethodB

Client -> MethodA -> MethodB

我希望事务仅从 MethodB 开始。 这是我的 spring 应用程序上下文中的片段:

<bean id="FooService"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager" />
    <property name="target" ref="FooServiceTarget" />
    <property name="transactionAttributes">
      <props>
        <prop key="MethodB">PROPAGATION_REQUIRED,-FooException</prop>
      </props>
   </property>
</bean>

但是,当我从客户端调用 MethodA 时,它不会在调用 MethodB 时创建事务代理。 如果我将 MethodA also 添加到应用程序上下文中的 bean 配置中,则会调用事务代理(按预期启动 MethodA)。 为什么会这样呢?我可以实现仅从MethodB开始创建交易吗?

I have a Spring+Hibernate application with declarative transaction management.
I have a service (FooService) which has 2 public methods MethodA and MethodB. The client will call the MethodA which in turn will call the MethodB.

Client -> MethodA -> MethodB

I want the transaction to start only from MethodB onwards.
This is a snippet from my spring application-context:

<bean id="FooService"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager" />
    <property name="target" ref="FooServiceTarget" />
    <property name="transactionAttributes">
      <props>
        <prop key="MethodB">PROPAGATION_REQUIRED,-FooException</prop>
      </props>
   </property>
</bean>

However, when I invoke the MethodA from my client, it doesn't create a transaction proxy when MethodB is to be called.
If I add MethodA also to the bean configuration in application-context, the transaction proxy is invoked (starting MethodA, as expected).
Why is this so? Can I achieve transaction being created only from MethodB onwards?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏日落 2024-12-09 10:21:08

客户端->方法A->方法B

我希望事务仅从 MethodB 开始

这是行不通的。方法 A 和方法 B 位于同一代理内。

唯一正确的做法是将方法 B 移至不同的 Bean 中。

顺便说一句:这个问题之前已经被问过很多次了,这里是我之前的一些答案:

Client -> MethodA -> MethodB

I want the transaction to start only from MethodB onwards

This can't work. Method A and Method B are inside the same proxy.

The only proper thing to do is to move method B into a different Bean.

BTW: this has been asked many times before, here are some previous answers of mine:

痴情 2024-12-09 10:21:08

我可以实现仅从MethodB开始创建交易吗?

仅当您 使用 AspectJ使用 Spring 进行字节码编织

为什么会这样?

Spring默认的AOP机制是JDK动态代理,它创建一个单独的 Proxy 实例来实现您的服务接口。该代理被注入到其他 bean 中代替您的服务,并且通过它的所有调用都将在委托给您的服务之前执行事务处理。由于从服务到自身的调用不通过代理,因此不能或不会启动任何事务。通过 AspectJ 字节码编织,事务代码将直接编织到您的服务中,并且它将正常工作。但是,如果您发现自己需要它来实现此目的,那么您很有可能需要将您的“服务”重构为至少两个独立的对象,因为这是一个信号,表明您在其中混合了关注点和/或交叉了抽象层。一节课。

Can I achieve transaction being created only from MethodB onwards?

Only if you use AspectJ bytecode weaving with Spring.

Why is this so?

Spring's default AOP mechanism is JDK dynamic proxies, which creates a separate Proxy instance that implements your service interface. This proxy is injected into other bean in place of your service, and all calls that go through it will do the transaction stuff before delegating to your service. Since a call from your service to itself doesn't go through the proxy, no transaction can or will be started. With AspectJ bytecode weaving, the transaction code will be woven directly into your service, and it will work fine. If you find yourself needing it for this purpose, though, it's a good bet that you need to refactor your "service" into at least two, separate objects because it's a signal that you've mixed up concerns and/or crossed abstraction layers in one class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文