目前我有一个JPA实体用于某种任务。某些进程写入该表,并且已调度的进程适用于该任务,并在准备就绪时更改状态。我需要对任务进行优先级排序,如果失败则以递减频率重试它们。我的环境是通过Hibernate + MySQL + XA事务的GlassFish 3 + JPA。从中期来看,该项目将用Spring解决方案取代GlassFish(使用Jetty等)。
它以某种方式工作了,但我对此并不满意:我得到了OptimisticLockExceptions,看起来我没有在某些时候得到正确的交易,而且GlassFish上的JPA定时器也有点混乱如果你需要变化的时间。
我觉得我在这里使用了错误的工具,我应该使用一些成熟,稳定的设计,而不是一起使用。使用JPA实体似乎是重量级的,但原始JDBC看起来更糟糕。当然我想避免繁重的库依赖,但是我可能会忽略一个简单的“罐头”解决方案来解决我的具体问题(这看起来并不那么罕见)。
[编辑]
为了澄清:我不会改变用例(我甚至不再使用代码),我只想获得一些通用指南,以便“下次正确”(TM) 。回答ben75的问题:工作者可能是多线程的,我需要小事务,因为这应该一直运行 - 可能持续数月。
答案 0 :(得分:1)
我认为你只需要尝试从上面看到的东西,以便确定过程中的角色&检测任务的创建者,任务的处理器和优先级控制器之间的依赖关系。之后,为每个角色设计清理可重用的EJB /服务。
有时,对于仅需10-20秒的相对较短的任务,强制用户使用异步EJB(搜索@Asynchronous
)而不是创建任务更有意义。
关于OptimisticLockExpcetions:这些可能会发生,因为数据同时发生变化,这可能是由任务使用者的其他线程之一或更改数据的客户端引起的。确定原因,如果是第一种情况,请更正错误。当然,如果你提供一些代码或解释一切如何运作,你会得到更多的帮助。
处理任务时:我会使用悲观锁获取任务实体,以便另一个线程不会开始处理相同的任务。
所以我认为你的过程很复杂,需要更好/更灵活的设计。