我有一个计划的执行程序服务,它在计时器上运行托管查询:
List<Tasks> running = null;
EntityManager em = null;
String query = "SELECT t FROM Tasks t WHERE t.state IN (:stateList)";
try
{
em = getEntityManager();
TypedQuery<Tasks> q = em.createQuery(query, Tasks.class);
q.setParameter("stateList", Arrays.asList(TaskState.RUNNING, TaskState.PENDING));
running = q.getResultList();
}
finally
{
closeEntityManager(em);
}
return running;
另一个线程执行任务并将其状态设置为完成,并且结束执行的结束时间。这是通过ID更新来实现的,我没有传递托管对象。
任务完成后很长时间,上面的查询会继续返回任务,其状态仍显示为正在运行且结束时间为空。
我查看了数据库,状态设置为完成,结束时间也是如此。
没有其他线程可以修改数据库行。
这几乎就像从缓存而不是数据库加载了行。这是确认的,因为当我重新启动应用程序时,行为消失。 有什么想法吗?
答案 0 :(得分:0)
您的交易边界是什么?我猜它是一个事务隔离问题,每次运行查询时它都应该在自己的事务中。否则,查询仅在事务开始时看到db状态。