我在我的应用程序中使用EJB3.1,该应用程序在JBoss AS 6上运行。我作为集成开发人员工作,我有一个用例,作为我的事务的一部分,通过REST多次调用各种外部系统, SOAP等。如果这些调用中的任何一个抛出异常,我必须将更改回滚到以前调用过的系统。
目前我有情况:
public class SystemAException extends RuntimeException {...}
public class SystemBException extends RuntimeException {...}
public class SystemCException extends RuntimeException {...}
系统类
public class SystemA{
public static makeChanges() throws SystemAException{...}
public static cancelChanges() {...}
}
public class SystemB{
public static makeChanges() throws SystemBException{...}
public static cancelChanges() {...}
}
public class SystemC{
public static makeChanges() throws SystemCException{...}
public static cancelChanges() {...}
}
呼叫
static makeChanges(Object o){
persist(o); //DB work
try {
SystemA.makeChange();
SystemB.makeChange();
SystemC.makeChange();
} catch(SystemBException eb){
SystemA.cancelChanges();
throw eb;
} catch(SystemCException ec){
SystemA.cancelChanges();
SystemB.cancelChanges();
throw ec;
}
update(o); //more DB work
}
我想摆脱try-catch并指示JBoss在发生RuntimeException时调用方法cancelChanges()
,就像它回滚对DB所做的更改一样。
我知道我可以使用Commander模式来撤消以前做过的更改,但我想知道容器是否能为我做到这一点。
如果有可能,我想完成以下事情
static makeChanges(Object o){
persist(o); //DB work
SystemA.makeChange();
SystemB.makeChange();
SystemC.makeChange();
update(o); //more DB work
}
答案 0 :(得分:0)
如果您通过REST / SOAP调用非XA外部系统,如果您的JVM /网络在撤消更改之前崩溃会发生什么?这听起来像一个脆弱的架构。
无论如何,无法让EJB容器自动为您执行此操作。我最好的想法是让SystemA / SystemB / SystemC调用TransactionSynchronizationRegistry.registerInterposedSynchronization,然后在事务回滚时通知您(因为如果系统异常或具有回滚的应用程序,EJB容器将自动回滚事务抛出= true),然后你可以尝试撤消任何东西。当然,如果JVM崩溃,那么你插入的同步监听器就会丢失而你无法撤消,所以它仍然无法解决这个问题。