ibm自由中的JTA事务配置

时间:2019-01-17 19:27:28

标签: java multithreading transactions websphere-liberty jta

我有一个MDB根据某些条件来触发进程(线程)。 process/thread是一个长期运行的过程,因此我们不想保留触发MDB的线程。

因此,我们创建了一个新线程,并自由地将其提交给托管任务执行程序,并在事情还没准备好时偶尔进入睡眠状态。

该线程从数据库读取记录,以消息形式发布到另一个MQ/JMS Queue,然后将记录写入数据库。

我希望MQ/JMS message和DB写入成为transaction的一部分-两者都应该一起成功/失败。

如何在IBM liberty environment中做到这一点。

任何建议/帮助都将受到赞赏。谢谢!!

我尝试用@TransactionalREQUIRES_NEW进行注释,但是不起作用。

通常,我们可能必须定义使用JTA transaction's,然后用@Transactional进行注释。

3 个答案:

答案 0 :(得分:3)

根据规范,

ManagedExecutorService任务不在事务下运行。但是,他们确实具有启动新交易的能力。您可以按照以下步骤进行操作,

executor.submit(() -> {
    UserTransaction tx = InitialContext.doLookup("java:comp/UserTransaction");
    tx.begin();
    try {
        try (Connection con = dataSource.getConnection()) {
            ResultSet results = con.createStatement().executeQuery(...);
            ... process result set and send messages
            ... update database
        }
    } finally {
        tx.commit(); // or tx.rollback
    }
    return null;
});

答案 1 :(得分:0)

当我们创建自己的线程时,容器不允许我们管理事务-特别是当我们在JMS会话上调用commit时。

以这种方式解决: 我从MDB调用异步会话bean。 容器本身管理此会话Bean的事务。 将消息和数据库事务发布到另一个会话Bean中,该会话Bean管理自己的事务(@TransactionManagement(value = TransactionManagementType.BEAN))。

在Bean托管方法中,注入UserTransaction对象: @资源     UserTransaction userTransaction;

然后使用:userTransaction.begin();管理交易。和userTransaction.commit();和userTransaction.rollback();

答案 2 :(得分:-1)

如果您正在谈论分布式系统,那么您就无法实现JMS消息的可转换性,无论如何您都会发送它。您应该使用幂等性。并且您对db的读写应该处于事务中。

交易:    -从数据库读取    -发送JMS    -写入db

即使服务失败并且您不继续进行交易,下一次您将再次发送JMS,但是JSM接收器服务将对该操作做出决定性的响应(只是忽略它)