是否可以通过不同的 EJB 3.1 和多个数据库服务器传播事务?

Is it possible to propagate a transaction through different EJB 3.1 and several database servers?

问题是这样的,我有三个 EJB,EJB_A 连接到服务器数据库 1,EJB_B 连接到服务器数据库 2,第三个 EJB_C负责调用前两个。

当 EJB_A 或 EJB_B 中出现错误时,仅在出现错误的 EJB 中执行回滚,在另一个正确保存的 EJB 上完成,尽管它应该将回滚传播到两个EJB.

EJB_C:

@Stateless
@LocalBean
@TransactionManagement( TransactionManagementType.BEAN )
public class EJB_C {

    private EJB_A ejbA;
    private EJB_B ejbB;

    @PostConstruct
    public void init(){
        Context context = null;
        try {
            context = new InitialContext();
            this.ayudanteSessionBean = (AyudanteSessionBean) context.lookup("java:global/Trans1/Trans1DBA/EJB_A");
            this.ayudanteSessionBean = (AyudanteSessionBean) context.lookup("java:global/Trans1/Trans1DBA/EJB_B");
        } catch (NamingException ex) {
            Logger.getLogger(OrquestadorSessionBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void saveTwoEJBs(EntityA, a, EntityB b){
        try{
            ejbA.save(a);
            ejbB.save(b);
        }catch (Exception ex) {

        }
    }
}

EJB_A:

@Stateless
@LocalBean
public class EJB_A {
    @PersistenceContext( unitName = "persistA" )
    private EntityManager em;

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void guardarAmigo(EntityA a){
        em.persist(a);
    }
}

EJB_B:

@Stateless
@LocalBean
public class EJB_B {
    @PersistenceContext( unitName = "persistB" )
    private EntityManager em;

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void guardarAmigo(EntityB b){
        em.persist(b);
    }
}

你能帮帮我吗?

好吧,要使其正常工作,您需要正确设置分布式事务 (XA):

  1. 检查所有数据源是否都支持 XA。通常这意味着不同的 jdbc 驱动程序 class 名称和不同类型的连接池在安装过程中。 该过程由供应商指定,但始终在您的应用程序服务器的文档中进行描述。
  2. 您需要删除注释:

    @TransactionManagement(TransactionManagementType.BEAN)

让你的容器(实际上是他的事务代理)来管理事务而不是bean。 3. 您需要在方法 saveTwoEJBs 上添加@TransactionAttribute 注解:

 @TransactionAttribute(TransactionAttributeType.REQUIRED)
public void saveTwoEJBs(EntityA, a, EntityB b)
  1. 这不是必需的,但没有理由通过 JNDI 上下文查找 EJB bean,只需通过 @EJB 注释注入它们:

    @EJB
    private EJB_A ejbA;
    @EJB
    private EJB_B ejbB;
    

一些链接:

http://docs.oracle.com/cd/E13222_01/wls/docs100/ejb30/examples.html http://docs.oracle.com/cd/E16439_01/doc.1013/e13981/servtran001.htm http://entjavastuff.blogspot.ru/2011/02/ejb-transaction-management-going-deeper.html