在我的应用程序中,两个线程尝试更新代码中的相同实体,如下所示:
public static <T> T updateEntity(T entity, long id) {
long start = System.currentTimeMillis();
EntityManager em = null;
EntityTransaction tx = null;
try {
em = GenericPersistenceManager.emf.createEntityManager();
tx = em.getTransaction();
tx.begin();
entity = em.merge(entity);
tx.commit();
LoggerMultiplexer.logDBAccess(start, System.currentTimeMillis(),
String.format(OPERATION_UPDATE_ENTITY, entity.getClass().getName(), id));
return entity;
}
...
有时,在提交行中出现重复的键错误。我猜这是在线程尝试同时更新实体时发生的。是否有可能?我想是这样,因为如果我在上面的函数中添加
synchronized
,我不会得到重复的键异常。那么,我是否必须考虑此类并发问题?如果是这样,如果我有多个线程试图更新同一对象,那将是正确的方法。
最佳答案
在单节点应用程序中,当从数据库中检索对象时,可以尝试在lock
(Session
)中使用Pessimistic versioning
对象。
有关locking的更多信息。关于hibernate concurrency的一些建议。
但是也许您应该重新考虑units of work
。添加locking
或synchronized
块将在您的应用程序上增加竞争。当您开发一些transaction basics时,最好记住这一点。缩短对象或Detached Object
模式的生命周期。使用Optimistic versioning
(例如,通过添加version
字段),然后在并发修改时处理错误。
关于multithreading - 不同的线程在 hibernate 中更新相同的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15210841/