我有一个非常简单的场景,涉及应用服务器(Glassfish)中的databaseJMS.情况非常简单:

1. an EJB inserts a row in the database and sends a message.
2. when the message is delivered with an MDB, the row is read and updated. 

问题是有时数据库中的message is delivered before the insert has been committed.如果我们考虑两阶段提交协议,这实际上是可以理解的:

1. prepare JMS
2. prepare database
3. commit JMS
4. ( tiny little gap where message can be delivered before insert has been committed)
5. commit database

这个问题我已经讨论了with others次,但答案总是:"Strange, it should work out of the box".

我的问题是:

  • 它怎么能开箱即用呢?
  • 我的情况听起来很简单,为什么没有更多的人有类似的问题呢?
  • 我做错什么了吗?有没有办法正确解决这个问题?

以下是关于我对这个问题的理解的更多细节:

只有按此顺序对待参与者时,才会存在时间问题.如果2PC以相反的顺序对待参与者(首先是数据库,然后是消息代理),那应该没问题.这个问题是随机发生的,但完全可以重现.

在JTA、JCA和JPA规范中,我发现没有办法控制分布式事务中参与者的顺序,在Glassfish文档中也是如此.我们可以假设它们将根据使用顺序被登记到分布式事务中,但是对于JPA这样的ORM,很难知道何时刷新数据以及何时真正使用数据库连接.有什么 idea 吗?

推荐答案

您正在经历典型的XA 2-PC竞争条件.在生产环境中确实会发生这种情况.

有三件事浮现在我的脑海里.

  1. 最后一个代理优化,其中JDBC是非XA资源.(失go 恢复语义)
  2. 有时间交付.(故意失go 实时性)
  3. 在JDBC代码中构建重试.(对功能的影响最小)

WebLogic有这个LLR优化,避免了这个问题,并为您提供了所有XA保证.

Database相关问答推荐

如何将对象源动态设置为子窗体

Postgres和Oracle之间 Select 查询的结果差异

当某些 node 死亡时,mongo 副本集选举如何表现?

存储具有公共链接但 ID 很长的用户文件是否安全?

如何使用 SQL Server 中的round方法将浮点数转换为 int?

任何必要的可空外键示例?

我如何知道 DynamoDB 表分布在多少个分区上?

发布 Oracle 和 SQL Server 性能测试是否违反许可?

哪个能够存储 1 亿条记录的嵌入式数据库具有高效的 C 或 C++ API

数据库供应商如何实现事务?

在 postgresql 中将列从字符串更改为字符串数组

当使用多个 WHEN MATCHED 语句时,它们是全部执行,还是只执行一个?

SqlAlchemy 中的动态表创建和 ORM 映射

Neo4j:逐步创建自动索引

您如何在数据库中构造配置数据?

MongoDB 和 PostgreSQL 的思考

如何在 Windows 中将用户添加到 PostgreSQL?

如何将特定的、可变的 order订单保存到数据库中

如何在 SQL Server 中总结时间字段

如何使用 group_concat 引用值