我想知道当您注释方法 @Transactional?当然,我知道春季会将该方法包裹在交易中。

但是,我有以下疑问:

  1. 我听说春天创造了一个 代理课?有人可以更多地解释吗 深度. 该代理类中实际存在的是什么?实际班级会怎样?以及我如何看到春季创建的代理班
  2. 我还阅读了春季文档:

注意:由于此机制基于代理,因此 只有通过代理进入的“外部”方法呼叫才会被拦截. 。这意味着“自我发电”,即目标对象中的一种方法调用目标对象的其他方法,即使标记了调用方法,也不会在运行时进行实际交易 @Transactional!

资源: http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html

为什么只有外部方法调用将在交易中而不是自我发电方法?

有帮助吗?

解决方案

这是一个大话题。 Spring参考文档专门为它提供多个章节。我建议阅读其中的 面向方面的编程交易, ,随着Spring的声明性交易支持使用AOP。

但是在很高的水平上,春季为声明的类创建代理 @transactional 在课堂本身或成员上。代理在运行时大多是看不见的。它为弹簧提供了一种方法,可以在方法中注入,之后或周围的方法呼叫为代理的对象。交易管理只是可以挂接的行为的一个示例。安全检查是另一种。而且,您也可以提供自己的伐木之类的东西。因此,当您注释一种方法时 @transactional, ,Spring动态创建一个代理,该代理实现与您注释的类相同的界面。当客户呼叫到您的对象时,呼叫会被拦截,并通过代理机制注入行为。

顺便说一句,EJB的交易类似地工作。

正如您观察到的那样,通过代理机制,只有在来自某些外部对象的呼叫中才能起作用。当您在对象内进行内部呼叫时,您确实会通过“这个“参考,绕过代理。但是,有一些解决该问题的方法。我解释了一种方法 这个论坛帖子 我使用的 BeanFactoryPostProcessor 将代理的实例注入运行时的“自我引用”类。我将此引用保存到称为““那么,如果我需要进行内部呼叫,以更改线程的交易状态,我将通过代理指导呼叫(例如”me.somemethod()“。)论坛帖子更详细地解释。请注意 BeanFactoryPostProcessor 现在,代码会有所不同,因为它是在春季1.x时间范围内编写的。但是希望它给你一个主意。我有一个更新的版本,我可能可以提供。

其他提示

当Spring加载您的BEAN定义并已配置为寻找 @Transactional注释时,它将在您的实际Bean周围创建这些代理对象。这些代理对象是在运行时自动生成的类的实例。调用方法时这些代理对象的默认行为只是为了在“ target” bean(即您的bean)上调用相同的方法。

但是,代理也可以与拦截器一起提供,当存在时,这些拦截器将在代理调用目标bean的方法之前被代理人调用。对于用@transactional注释的目标豆,Spring将创建一个TransActionInterceptor,并将其传递给生成的代理对象。因此,当您从客户端代码调用该方法时,您正在调用代理对象上的方法,该对象首先调用TransActionInterceptor(开始交易),从而又调用目标BEAN上的方法。当调用完成时,TransactionInterceptor会承诺/滚动交易。它与客户端代码透明。

至于“外部方法”的事情,如果您的Bean调用了其自己的一种方法,那么它将不会通过代理进行。请记住,春天将您的豆包装在代理中,您的豆对此一无所知。只有来自“外部”的bean呼叫您的豆通过代理。

这有帮助吗?

作为一个视觉人,我喜欢用代理模式的序列图来称重。如果您不知道如何阅读箭头,我会读第一个: Client 执行 Proxy.method().

  1. 客户从他的角度来调用目标的方法,并被代理人默默拦截
  2. 如果定义了之前的方面,则代理将执行它
  3. 然后,执行实际方法(目标)
  4. 返回和后启动是可选的方面,该方法返回后执行和/或如果该方法引发异常
  5. 之后,代理执行后面(如果定义)
  6. 最后,代理返回呼叫客户端

Proxy Pattern Sequence Diagram(我被允许在我提到其起源的条件下发布照片。作者:Noel Vaes,网站:www.noelvaes.eu)

最简单的答案是 无论您在哪种方法上声明 @transactional,交易边界启动和边界完成后结束。

如果您使用的是JPA调用,则所有提交都在此交易边界中。假设您正在保存实体1,实体2和实体3。现在,当保存实体3发生一个例外时,Asitiy1和entity2进行了相同的交易,因此Entity1和Entity2将对Entity进行回滚3。

交易:( entity1.save,entity2.save,entity3.save)。任何例外都会导致所有JPA交易与DB的回滚。 春季使用内部JPA交易。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top