2014-01-21 56 views
2

我正在使用Hibernate和Spring,并且我想编写服务代码以满足在两个单独的线程中使用DAO来获取实体实例通过id,并且它在每种情况下都是相同的id /数据库行,并且我不希望给定的方法在该实体实例的两个线程中同时运行。如何编写在实体实例上同步的Java代码

我不知道是否有可能写...

synchronized(entity) {} 

或者这是否是不可能的,因为从DAO检索时,每个线程可以创建在内存中的对象的不同实例,都指的是同一个实体实例。

如果Hibernate确实可以在内存中为同一个实体实例创建多个对象,那么执行我想要做的事情的最佳方法是什么?

+0

private static Object sharedLock = new Object();你可以使用共享锁吗? –

回答

2

这是行不通的。当您从数据库加载数据时,Hibernate可能(并且经常会)返回不同的实例。

原因是两个线程可能想要同时访问同一个对象。如果Hibernate会给出同一个实例,那么通过一个线程的更改可能(或不)对第二个线程可见。

为了达到您想要的效果,您需要一个中央注册表,您可以通过ID获取实体的锁定。这样,每个线程都可以这样做:

Object lock = lockFactory.getLock(id); 
synchronized(lock) {...} 

然后,工厂可以确保所有线程都获得相同ID的同一个锁。

+0

谢谢Aaron,这正是我需要的解决方案。不允许投票给你,因为我没有任何声望:) –

+0

伟大的学习对我来说也是:) –

+1

@Aaron我明白你建议的注册表将保持对锁对象的引用。随着时间的推移,这些尺寸可以达到很大的尺寸,您是否对这些物体如何清洁有任何想法。谢谢 –