【发布时间】:2015-03-14 04:01:21
【问题描述】:
假设我有两个不同的线程,T1 和 T2,同时访问同一个数据库并从同一个表中获取数据。
现在在线程启动时,我需要从表中获取数据并将行存储到一个集合中,然后我将使用它在其他地方执行一些工作。我不希望两个线程能够处理相同的数据,因为这会导致重复(和长时间)工作。更具体地说,这是一个企业应用程序,需要在启动时加载一些记录并将其存储在一个集合中以做一些额外的工作。问题是在集群环境中,这可能导致两个不同的实例加载相同的数据,因此工作可能会重复。所以我希望单个实例只加载一次行。
如何避免这种情况?
我目前正在使用 Hibernate 和 Oracle 10g。到目前为止,这些是我的解决方案:
以编程方式锁定行。读取它的第一个将某些“锁定”列设置为 true,但如果第一个线程在未将行设置为“已处理”的情况下死亡,则很可能发生死锁。
使用悲观锁定。我尝试使用 LockMode.UPGRADE 但这似乎没有帮助,因为我仍然能够同时从两个线程读取数据。
public List<MyObject> getAllNtfFromDb() { Session session = HibernateUtil.getOraclesessionfactory().openSession(); Query q = session.createQuery( "from MyObject n where n.state = 'NEW'"); List<MyObject> list = (List<MyObject>) q.list(); for (int i=0; i<list.size(); i++) session.lock(list.get(i), LockMode.UPGRADE); return list; }
还有其他提示吗?我究竟做错了什么?
谢谢。
【问题讨论】:
-
也许您可以使用 select for update 语句?
-
您能否提供用于此行的 Hibernate 导入:
Session session = HibernateUtil.getOraclesessionfactory().openSession();
标签: java oracle hibernate transactions locking