【发布时间】:2012-10-27 13:18:16
【问题描述】:
我将尝试描述我要解决的问题。我意识到我开发的一个应用程序的 Spring 事务管理实现得很差。我在 DAO 接口方法 (CRUD) 上定义事务,而不是在服务层方法上使用声明性方法。它是一个 Web 应用程序,它执行某种消息处理,并且多个线程同时对同一个消息实例进行操作。以下是典型顺序中的步骤:
- 消息在 T1(事务 1)中创建并放入出站队列。 T1 已终止。
- 消息由不同的线程从队列中取出,发送并更新发送时间和一些附加信息。设置消息对象的属性并调用 dao.update(m),t2 开始。
- 在 t2 提交之前,收到传递报告,Tread3 开始处理相同的消息对象,方法是在 db 中找到它(保存在步骤 1 中),更新它的 state 属性并调用 dao.upate(m),因此 t3 在 t2 仍然存在时开始进行中。
- 另一个线程(线程 4)通过在 t4 中再次更改其状态来进一步处理相同的消息对象。
时不时出现的结果是t2的变化丢失,db中的发送时间为null。 我需要帮助来弄清楚如何改进应用设计并通过阻止并发处理同一条消息来消除此问题。
我应该专注于事务重新设计(在服务级别而不是 dao 上使用它)并使用可序列化的隔离级别(或其他)还是
我应该使用 JPA 实体管理器锁定吗?
应用使用 Spring 3 和 JPA2 以及休眠实现。
【问题讨论】:
-
消息是如何发送的? JMS?网络服务?其他?您能否将这部分作为全局分布式事务(在 JMS 的情况下)?如果不是,您不应该在 T2 完成后简单地发送消息,从而确保在收到传递报告时 T2 已经结束?
-
消息通过第三方网络服务发送。 T2 在发送消息之前无法执行,因为消息已随发送结果更新。
标签: java spring hibernate jpa-2.0