在我的应用程序中,两个线程尝试在代码中更新相同的实体,如下所示:
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
,我就不会得到重复的键异常。那么,我是否必须考虑这种并发问题?如果是这样,如果我有多个线程试图更新同一个对象,那么正确的方法是什么。
答案 0 :(得分:1)
在单个节点应用程序中,当您从数据库中检索对象时,可以尝试lock
(Session
)中的Pessimistic versioning
个对象。
有关locking的更多信息。关于hibernate concurrency的一些建议。
但也许你应该重新考虑一下units of work
。添加locking
或synchronized
块会在您的应用程序中添加高争用。当你发展一点transaction basics时,最好记住。缩短对象的寿命或Detached Object
模式。使用Optimistic versioning
(例如,通过添加version
字段)然后处理并发修改时的错误。