【问题标题】:Synchronization issue with JMS and JPAJMS 和 JPA 的同步问题
【发布时间】:2011-09-06 10:13:57
【问题描述】:

我有一种情况,我需要通过JMS(分组消息)接收大文件的一部分并将其存储在数据库中。

问题是组中的每条消息将是TABLE A 中的一行,并且@ManytoOneTABLE B 之间存在关联。这意味着对于一组,表 B 中只有一个条目,但表 A 中有许多条目。

我目前的逻辑是,在插入table A 之前,我正在检查任何条目(@NamedQuery,因为当时MDB 不知道主键),如果没有找到,创建一个新的(在这里创建Table B的主键)。

由于MDB 有多个实例接收同一组中的消息,table B 中的条目对于同一消息组会重复,因为尚未提交 MDB 中首先为表 B 创建条目的事务.

为了更清楚:

第 1 步:接收消息。

步骤2:创建TABLE A所需的实体。检查表B中是否存在具有相同组ID的条目(READ),如果找到,则设置关系并持久化,如果没有,则为表创建新实体B(WRITE)(通过服务生成的主键)设置关系并持久化。

问题是,MDB 的多个实例为表 B 创建条目,因为它无法在 READ 期间找到条目(由第一个 MDB 创建),因此 WRITING 为同一组 ID 新条目。

有什么办法可以克服这个问题吗? 1.我使用的是eclipselink和Oracle,容器管理的事务和实体管理器是使用@PersistenceContext注解注入的。

谢谢

【问题讨论】:

  • 因为拥有超过 1 个 mdb 并不能保证您获得更高的吞吐量(猜测在您的用例中 db 是最大的因素),因此将允许的 MDB 实例数限制为1?通过部署描述符很容易做到。 Glassfish 服务器?

标签: java jakarta-ee jpa asynchronous eclipselink


【解决方案1】:

不确定自己在做什么?您是要阻止两个事务创建一个新的 A,还是只创建一个新的 B?

您可以在 B 表中的 A 外键上添加唯一约束。这将确保为 A 插入 B 的第二次尝试将失败。

另一种解决方案是在A上为事务使用悲观锁,这样可以保证事务不冲突。

您也可以通过强制 A 的版本递增来使用乐观锁,这将导致第二次尝试失败。实际上,由于 A 对 B 有 ManyToOne,它的版本应该增加,所以你应该已经得到了一个锁定错误。

【讨论】:

    猜你喜欢
    • 2015-01-22
    • 2012-03-13
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    • 2012-06-03
    • 2019-02-03
    相关资源
    最近更新 更多