Spring - @Transactional - 后台会发生什么? [英] Spring - @Transactional - What happens in background?

查看:36
本文介绍了Spring - @Transactional - 后台会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道当您使用 @Transactional 注释方法时实际发生了什么?当然,我知道 Spring 会将该方法包装在一个事务中.

但是,我有以下疑问:

  1. 我听说 Spring 创建了一个代理类?有人可以更深入解释这一点.那个代理类中究竟有什么?实际的班级会发生什么?以及如何查看 Spring 创建的代理类
  2. 我还在 Spring 文档中读到:

<块引用>

注意:由于此机制基于代理,只有通过代理传入的外部"方法调用才会被拦截.这意味着自调用",即目标对象中的一个方法调用目标对象的其他方法,即使被调用的方法被标记为 @Transactional!

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

为什么只有外部方法调用会在事务下而不是自调用方法?

解决方案

这是一个很大的话题.Spring 参考文档为它提供了多个章节.我建议阅读 Aspect-Oriented 上的那些编程交易,因为 Spring 的声明式事务支持在其基础上使用 AOP.

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

顺便说一下,EJB 中的事务的工作方式类似.

正如您所观察到的,代理机制仅在调用来自某个外部对象时才起作用.当您在对象内进行内部调用时,您实际上是通过绕过代理的 this 引用进行调用.然而,有一些方法可以解决这个问题.我在 this forum post 中解释了一种方法,其中我使用了 BeanFactoryPostProcessor 将代理的实例注入自引用";运行时的类.我将此引用保存到名为 me 的成员变量.然后如果我需要进行需要更改线程事务状态的内部调用,我会通过代理直接调用(例如me.someMethod().)论坛帖子有更详细的解释.

请注意,BeanFactoryPostProcessor 代码现在会有些不同,因为它是在 Spring 1.x 时间范围内写回的.但希望它能给你一个想法.我有一个更新版本,我可能可以提供.

I want to know what actually happens when you annotate a method with @Transactional? Of course, I know that Spring will wrap that method in a Transaction.

But, I have the following doubts:

  1. I heard that Spring creates a proxy class? Can someone explain this in more depth. What actually resides in that proxy class? What happens to the actual class? And how can I see Spring's created proxied class
  2. I also read in Spring docs that:

Note: Since this mechanism is based on proxies, only 'external' method calls coming in through the proxy will be intercepted. This means that 'self-invocation', i.e. a method within the target object calling some other method of the target object, won't lead to an actual transaction at runtime even if the invoked method is marked with @Transactional!

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

Why only external method calls will be under Transaction and not the self-invocation methods?

解决方案

This is a big topic. The Spring reference doc devotes multiple chapters to it. I recommend reading the ones on Aspect-Oriented Programming and Transactions, as Spring's declarative transaction support uses AOP at its foundation.

But at a very high level, Spring creates proxies for classes that declare @Transactional on the class itself or on members. The proxy is mostly invisible at runtime. It provides a way for Spring to inject behaviors before, after, or around method calls into the object being proxied. Transaction management is just one example of the behaviors that can be hooked in. Security checks are another. And you can provide your own, too, for things like logging. So when you annotate a method with @Transactional, Spring dynamically creates a proxy that implements the same interface(s) as the class you're annotating. And when clients make calls into your object, the calls are intercepted and the behaviors injected via the proxy mechanism.

Transactions in EJB work similarly, by the way.

As you observed, through, the proxy mechanism only works when calls come in from some external object. When you make an internal call within the object, you're really making a call through the this reference, which bypasses the proxy. There are ways of working around that problem, however. I explain one approach in this forum post in which I use a BeanFactoryPostProcessor to inject an instance of the proxy into "self-referencing" classes at runtime. I save this reference to a member variable called me. Then if I need to make internal calls that require a change in the transaction status of the thread, I direct the call through the proxy (e.g. me.someMethod().) The forum post explains in more detail.

Note that the BeanFactoryPostProcessor code would be a little different now, as it was written back in the Spring 1.x timeframe. But hopefully it gives you an idea. I have an updated version that I could probably make available.

这篇关于Spring - @Transactional - 后台会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆