一尘不染

Spring-@Transactional-后台会发生什么?

java

我想知道当你使用注释方法时实际发生了@Transactional什么?当然,我知道Spring将把该方法包装在Transaction中。

但是,我有以下疑问:

  1. 听说Spring创建了代理类?有人可以更深入地解释这一点。该代理类中实际包含什么?实际班级会怎样?我怎么能看到Spring创建的代理类
  2. 我还在Spring文档中读到:

注意:由于此机制基于代理,因此仅会拦截通过代理传入的“外部”方法调用。这意味着“自调用”,即目标对象内的一种调用目标对象其他方法的方法,即使被调用的方法标有@Transactional!,也不会在运行时导致实际事务。


阅读 280

收藏
2020-03-02

共1个答案

一尘不染

这是一个大话题。Spring参考文档对此进行了专门的介绍。我建议阅读有关面向方面的编程和事务的内容,因为Spring的声明性事务支持使用AOP作为基础。

但是在非常高的层次上,Spring为在类本身或成员上声明@Transactional的类创建代理。代理在运行时几乎不可见。它为Spring提供了一种在方法调用之前,之后或周围将行为注入到被代理对象中的方式。事务管理只是可以挂接到的行为的一个示例。安全检查是另一个。您也可以提供自己的日志记录之类的东西。因此,当您使用@Transactional注释方法时,Spring会动态创建一个代理,该代理实现与要注释的类相同的接口。当客户端对您的对象进行调用时,这些调用将被拦截,并通过代理机制注入行为。

顺便说一下,EJB中的事务工作类似。

如您所见,通过代理机制,仅当调用来自某个外部对象时才起作用。当在对象内进行内部调用时,实际上是通过“ this ”引用进行调用,该引用绕过了代理。但是,有一些方法可以解决该问题。我在此论坛帖子中解释了一种方法,其中使用BeanFactoryPostProcessor在运行时将代理实例注入“自引用”类中。我将此引用保存到一个名为“ me ” 的成员变量。然后,如果需要进行需要更改线程事务状态的内部调用,则可以通过代理将调用定向(例如“ me.someMethod()“。)论坛帖子中有更详细的解释。请注意,BeanFactoryPostProcessor代码现在有所不同,因为它是在Spring 1.x的时间框架中写的。但是希望它能给您一个想法。我有一个更新的版本,我可能可以提供。

2020-03-02