gpt4 book ai didi

java - AOP、Spring 和事务范围界定

转载 作者:搜寻专家 更新时间:2023-11-01 03:14:58 25 4
gpt4 key购买 nike

想象一个使用 spring、jdbc 和 aop 的事务性多线程 java 应用程序,m 个包中有 n 个类,所有这些都参与数据库事务。现在假设需要在一个事务中确定一组任意类的范围。此外,在调用时提交事务的范围内总是有一个类 T。

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

实例可以相互调用,并且如前所述,没有一个公共(public)入口点可以从单个入口点(如服务层)调用所有实例,这将成为 spring 事务标记的简单目标。

现在的问题是:这个问题可以用 aspects 来解决吗?如果是这样,基本方法是什么?谢谢。

最佳答案

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

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

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


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

而且,很明显,这是一种 hack,我不提倡在未开发的系统中这样做 :)。

关于java - AOP、Spring 和事务范围界定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/997600/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com