gpt4 book ai didi

java - 在一个也使用aop的方法上使用spring的@Transactional :after advice

转载 作者:行者123 更新时间:2023-12-02 03:00:48 26 4
gpt4 key购买 nike

我想看看是否已经有类似的问题,但找不到,所以就在这里。

我们有一个遗留代码,其中单个 BO 使用反射对许多 DAO 进行方法调用。为了简单起见,我修改了代码。

@Transactional
class EndpointData1DAO implements DAO{
void inserData() {
// insert data 1
}
}

@Transactional
class EndpointData2DAO implements DAO{
void inserData() {
// insert data 2
}
}

class MachoBO {
void handleEverything(String daoName) {
DAO dao = getDAOUsingReflection(daoName);
dao.insertData();
}
}

问题是,需求发生了变化,因此当在 EndpointData1DAO 上调用 insertData() 时,EndpointData2DAO 的 insertData 也必须被调用。

我可以简单地将 EndpointData2DAO 添加为 EndpointData1DAO 的成员,但这严重违反了 SRP 并使其变得丑陋。

所以我编写了一个注释 @ExecuteAfter(clazz=EndpointData2DAO.class, method="insertData") ,它获取 EndpointData2DAO 的实例并调用 insertData(),在执行它所注解的类的方法之后,通过使用aop:after,使得给定

@Transactional
@ExecuteAfter(clazz=EndpointData2DAO.class, method="insertData")
class EndpointData1DAO implements DAO{
void inserData() {
System.out.println("insert1");
}
}

@Transactional
class EndpointData2DAO implements DAO{
void inserData() {
System.out.println("insert2");
}
}

class MachoBO {
void handleEverything(String daoName) {
DAO dao = getDAOUsingReflection(daoName);
dao.insertData();
}

12将在调用 machoBO.handleEverthing("Data1");

时打印出来

现在我的问题是,EndpointData1DAO 和 EndpointData2DAO 的 insertData() 会在同一个物理事务中吗?换句话说,EndpointData2DAO的insertData()中的运行时异常会回滚EndpointData1DAO的insertData()插入的数据吗?

提前多谢~!!

最佳答案

我通过实际运行测试找到了答案。

通过执行以下代码,我能够找到当前正在运行的事务的名称。

ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
Class tsmClass = contextClassLoader.loadClass("org.springframework.transaction.support.TransactionSynchronizationManager");
String transactionName = (String) tsmClass.getMethod("getCurrentTransactionName", null).invoke(null, null);
System.out.println(transactionName);

并且发现当我把@MachoBO 上的事务如下,

@Transactional
class MachoBO {
void handleEverything(String daoName) {
DAO dao = getDAOUsingReflection(daoName);
dao.insertData();
}

由于@Transactional具有“方法范围”,当machoBO.handleEverthing("Data1");被调用时,两个 DAO 的 inserData() 在事务名称“MachoBO.handleEverthing”下执行。

但是,当 MachoBO 没有使用 @Transactional 注解时,两个 DAO 的 insertData() 不共享相同的方法范围,因此,在单独的事务下执行,即“EndpointData1DAO.inserData”和“EndpointData2DAO.insertData”。

但应该注意(尽管很明显),当 DAO 使用 @Transactional 注释且传播设置为 REQUIRES_NEW 时,DAO 的 insertData() 在单独的事务中运行。

关于java - 在一个也使用aop的方法上使用spring的@Transactional :after advice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6344352/

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