我想知道当您用@Transactional
注释方法时实际发生了什么?
当然,我知道Spring将把该方法包装在Transaction中。
但是,我有以下疑问:
资料来源:http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html
为什么只有外部方法调用将在Transaction下而不是在自调用方法下?
最佳答案
这是一个大话题。 Spring引用文档对此进行了专门的介绍。我建议阅读Aspect-Oriented Programming和Transactions上的内容,因为Spring的声明式事务支持使用AOP作为基础。
但是在很高的层次上,Spring为在类本身或成员上声明 @Transactional 的类创建代理。代理在运行时几乎不可见。它为Spring提供了一种在方法调用之前,之后或周围将行为注入(inject)到被代理对象中的方式。事务管理只是可以挂钩的行为的一个示例。安全检查是另一个。您也可以提供自己的日志记录之类的东西。因此,当您使用 @Transactional 注释方法时,Spring会动态创建一个代理,该代理实现与要注释的类相同的接口(interface)。当客户端对您的对象进行调用时,这些调用将被拦截,并通过代理机制注入(inject)行为。
顺便说一下,EJB中的事务工作类似。
如您所见,通过代理机制,仅当调用来自某个外部对象时才起作用。在对象内进行内部调用时,实际上是通过“此”引用进行调用,该引用绕过了代理。但是,有一些方法可以解决该问题。我解释了this forum post中的一种方法,其中我使用 BeanFactoryPostProcessor 在运行时将代理实例注入(inject)“自引用”类中。我将此引用保存到一个名为“ me ”的成员变量。然后,如果需要进行需要更改线程事务状态的内部调用,则可以通过代理定向该调用(例如“ me.someMethod()”。)论坛帖子中会更详细地说明。注意, BeanFactoryPostProcessor 代码现在会有所不同,因为它是在Spring 1.x时间范围内写回的。但希望它能给您一个想法。我有一个可能会提供的更新版本。