2013-03-04 65 views
2

更新同一个对象在我的应用程序两个纱线尝试在代码更新相同的实体如下:不同的线程处于休眠

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; 

    } 
    ... 

有时候,我在提交线得到重复键错误。我想这是在线程尝试同时更新实体时发生的。可能吗?我认为是这样,因为如果我将​​添加到上面的函数中,我不会得到重复键异常。那么,我是否必须考虑这种并发问题?如果是这样,如果我有多个线程试图更新同一个对象,那么正确的方法是什么。

回答

1

在单节点应用程序中,您可以尝试从SessionPessimistic versioning)中的lock对象从DB中检索它们时。

更多关于locking。并有关于hibernate concurrency的一些建议。

但也许你应该重新考虑你units of work。添加locking或​​块会在您的应用程序中添加较高的争用。当你开发一些transaction basics时最好记住它。缩短物体的使用寿命或减少模式的使用寿命。使用Optimistic versioning(例如,通过添加一个version字段),然后处理并发修改错误。

+0

实际上,我尝试更新的实例对象在应用程序生存时间内存在内存中。不同的服务更新实体的不同字段。当发生更新时,通过上述合并操作将其写入数据库。我想我应该看看您提供的链接以获得洞察力,谢谢。 – suat 2013-03-04 22:26:37