我试图看看是否已经有类似的问题,但是找不到它,就在这里。
我们有一个遗留代码,其中单个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();
}
1 2 将在调用machoBO.handleEverthing(“Data1”);
时打印出来现在我的问题是, 将EndpointData1DAO和EndpointData2DAO的insertData()置于同一物理事务中? 换句话说,EndpointData2DAO的insertData()中的运行时异常是否会回滚EndpointData1DAO'insertData()所插入的数据?
提前多了〜!!
答案 0 :(得分:0)
我通过实际运行测试找到了答案。
通过执行以下代码,我能够找到当前正在运行的事务的名称。
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如下,
@Transactional
class MachoBO {
void handleEverything(String daoName) {
DAO dao = getDAOUsingReflection(daoName);
dao.insertData();
}
因为@Transactional有一个“方法范围”,
调用machoBO.handleEverthing("Data1");
时
两个DAO的inserData()在事务名称“MachoBO.handleEverthing”下执行。
但是,当MachoBO未使用@Transactional注释时, 两个DAO的inserData()不共享相同的方法范围,&因此, 在单独的事务下执行,即“EndpointData1DAO.inserData”和“EndpointData2DAO.insertData”。
应该注意的是(虽然很明显)在DAO使用@Transactional注释并且传播设置为REQUIRES_NEW的情况下,DAO的insertData()在单独的事务中运行。