AOP,春季和交易范围 [英] AOP, Spring and transaction scoping

查看:87
本文介绍了AOP,春季和交易范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一个使用spring,jdbc和aop的事务性多线程Java应用程序,其中m个包中的n个类都参与数据库转换.现在,我们需要在一个事务中限定任意一组类的范围.此外,在范围内总有一个类T在被调用时提交事务.

imagine a transactional, multithreaded java application using spring, jdbc and aop with n classes in m packages all taking part in database transations. Now let's say there is the need to scope an arbitrary set of classes within one transaction. Furthermore there is always one class T within the scope that commits the transaction when called.

为了清楚起见,让我举个例子: 给定包A,B,Z和类A.Foo,B.Bar和Z.T. 调用了各个类的以下实例(可能是由不同的调用者以及介于两者之间的其他类):A.Foo,B.Bar,A.Foo,Z.T 仅在调用Z.T之后才提交事务.如果应用程序由于任何原因而关闭,除非Z.T参与其中,否则交易将永远不会提交.

Let me give an example for clarity: Given the packages A,B,Z and classes A.Foo, B.Bar and Z.T. The following instances of the respective classes are called (possibly by different callers with other classes in between): A.Foo,B.Bar,A.Foo,Z.T The transactions will be committed only after Z.T is called. Should the application shut down for whatever reason the transaction will never be committed unless Z.T gets involved.

实例可以相互调用,并且如上所述,没有通用的入口点从单个入口点(例如服务层)调用所有实例,这很容易成为spring的事务标记的目标.

Instances can call each other and, as already mentioned, there is no common entry point calling all instances from a single point of entry (like a service layer) which would make an easy target for spring's transactional tag.

现在的问题是:可以使用方面解决此问题吗?如果是这样,基本方法是什么? 谢谢.

Now the question: can this problem be solved using aspects ? If so, what could be the basic approach ? Thanks.

推荐答案

您不需要单个入口点,但是您确实需要能够将事务拦截器应用于所有入口点,以便可以重入调用参与同一笔交易.假设您可以执行此操作,则可以使用ThreadLocal标志和自定义的org.springframework.transaction.support.TransactionSynchronization实现来完成此操作.

You don't need a single point of entry, but you do need the ability to apply the transactional interceptor to all entry points so that re-entrant calls can participate in the same transaction. Assuming that you can do that, you could accomplish this with a ThreadLocal flag and a custom org.springframework.transaction.support.TransactionSynchronization implementation.

您可以修改Z.T以在安全进行提交时设置ThreadLocal标志.在从PlatformTransactionManager调用的TransactionSynchronization.beforeCommit()实现中,可以检查该标志并使用该标志来确定是否允许继续进行提交.如果不存在该标志,则可以抛出RuntimeException来强制回滚.

You'd modify Z.T to set the ThreadLocal flag when a commit is safe to proceed. In your TransactionSynchronization.beforeCommit() implementation, which is invoked from the PlatformTransactionManager, you can check the flag and use that to determine whether to allow the commit to proceed. You can force a rollback by throwing a RuntimeException if the flag is not present.

一个警告是,如果您有其他类型的事务(不涉及您描述的3个协调类),则需要确保它们不会无意间回滚.为此,您可以通过另一个ThreadLocal标志在A.Foo,B.Bar和Z.T中标记此特殊交易",然后在上述beforeCommit()方法中的guard子句中检查该标志.伪代码:

One caveat would be if you have other types of transactions (that don't involve the 3 co-ordinating classes you've described), you'll need to ensure that they don't get rolled back inadvertently. To do this, you could flag this "special transaction" in A.Foo, B.Bar and Z.T via another ThreadLocal flag, then check that flag in a guard clause in the beforeCommit() method mentioned above. Pseudocode:


void beforeCommit() {
  if in special transaction
    if commit flag not set
       throw new RuntimeException("cancel transaction")
    end if
  end if
end

而且,显然,这是一个hack,我不主张在未开发的系统中这样做:).

And, obviously, this is a hack and I wouldn't advocate doing in a greenfield system :).

这篇关于AOP,春季和交易范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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