Spring事务内部
情况如下:
-
Method1中有四种数据库更新方法。 Method1使用Spring事务管理语义进行注释。
-
Method2中有一个数据库读取方法,并在Method1完成所有数据库更新后调用它。 Method2也使用Spring事务语义进行注释。
-
有一个Web请求进入,控制器拦截请求并调用method1然后调用method2。
-
事务也包含在Web请求中。
我有兴趣知道的是:
1. Spring如何知道在成功交易后提交数据库更新? 是否有一些引用进行事务管理的Spring实现?
2.由于我们有一个事务层次结构:围绕web-request-> Transaction with Propagation的事务= RequestNew for Method1-> Transaction with Propagation = Method2是必需的,Spring如何进行事务管理以确保事务在正确的上下文与正确的顺序?
简而言之,通过游戏来了解Spring如何在其所有最复杂的细节中执行事务管理或者不仅仅是简单地手动挥动以JTA或其他缩写为中心的解释的文档。
谢谢
让我们做一些基本的陈述。
- 事务上下文是一种环境,其中某些特殊属性(数据库会话)可供应用程序运行时使用,否则这些属性不可用。 事务上下文通常用于确定事务的范围。
- Spring使用AOP Proxies和XML元数据来实现声明式事务管理。
- 注释用于标记特定方法的事务传播行为。
- Spring使用Interceptor Mechanism在方法上应用事务。
在这里,我重用上面的@stacker给出的示例
MyClass{ @Transactional public void sequence() { method1(); method2(); } @Transactional void method1() { } @Transactional(propagation=Propagation.REQUIRES_NEW) void method2() { } }
您也可以使用xml配置实现相同的function。 让我们把它作为它的流行和广泛使用。
在部署时
- Spring框架检查xml配置文件(着名的
applicationContext.xml
),并根据配置扫描代码以查找@Transactional
注释(假设配置被提及为基于注释)。 - 在此之后,它为标记为事务的方法生成 AOP代理。 简单来说,这些代理只不过是有关方法的包装。
- 在这些包装器方法中,还根据配置(即事务传播)生成Transaction Advisor代码之前和之后。
- 现在,当调用这些包装器方法时, 事务顾问会在实际方法调用之前和之后进入图片。 。
-
在上面的例子的伪代码中表示相同
ProxyMyClass{ MyClass myclass; . . . sequence(){ //Transaction Advisor code (Typically begin/check for transaction) myclass.sequence(); //Transaction Advisor code(Typically rollback/commit) } . . . }
这就是春季经理人的交易方式。 虽然稍微过于简单化了。
现在回答你的问题,
Spring如何知道在成功交易后提交数据库更新? 是否有一些引用进行事务管理的Spring实现?
无论何时在事务中调用方法,实际上都会调用一个代理,该代理首先执行事务顾问(将开始事务),然后调用实际的业务方法,一旦完成,另一个事务顾问执行(这取决于返回的方法) ,将提交或回滚事务)。
由于我们有一个事务层次结构:围绕web-request-> Transaction with Propagation的事务= RequestNew for Method1-> Transaction with Propagation = Method2是必需的,Spring如何进行事务管理以确保事务在适当的上下文中执行订单是否正确?
在事务层次结构的情况下,spring框架会相应地生成Transaction Advisor检查。 对于你提到的例子,
- for method1(RequestNew)事务Advsor代码(或事务建议)将始终创建一个新事务。
- for method2(必需)Transaction Advisor代码(或事务建议)将检查现有事务,如果存在则使用相同的事务,或者创建新事务。
弹簧文档页面上有一个图像 ,非常好地总结了这些方面。
希望这可以帮助。
Controller @Transactional public void sequence() { method1(); method2(); } @Transactional void method1() { } @Transactional(propagation=Propagation.REQUIRES_NEW) void method2() { }
默认传播是REQUIRED(支持当前事务,如果不存在则创建一个新事务。)因此m1将使用Controller中启动的事务。 m2注释为REQUIRES_NEW(创建一个新事务,暂停当前事务(如果存在)。事务的顺序是您调用事务方法的顺序。
Controller begin tx1 |--------------------> m1 (uses tx1) | | begin tx2 |--------------------> m2 (uses tx2) | commit tx2 commit tx1
你读过Spring文档吗? 基本上AOP用于管理交易。 您还应该阅读AOP文档 。 如果AOP文档不够,我建议你仔细阅读代码。 使用断点在调试模式下单步调试代码会很好。