创建自定义回滚方法EJB3

时间:2015-04-15 17:31:01

标签: java jboss transactions ejb jboss6.x

我在我的应用程序中使用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
}

1 个答案:

答案 0 :(得分:0)

如果您通过REST / SOAP调用非XA外部系统,如果您的JVM /网络在撤消更改之前崩溃会发生什么?这听起来像一个脆弱的架构。

无论如何,无法让EJB容器自动为您执行此操作。我最好的想法是让SystemA / SystemB / SystemC调用TransactionSynchronizationRegistry.registerInterposedSynchronization,然后在事务回滚时通知您(因为如果系统异常或具有回滚的应用程序,EJB容器将自动回滚事务抛出= true),然后你可以尝试撤消任何东西。当然,如果JVM崩溃,那么你插入的同步监听器就会丢失而你无法撤消,所以它仍然无法解决这个问题。