不同的线程在hibernate中更新同一个对象

时间:2013-03-04 20:48:52

标签: multithreading hibernate concurrency merge

在我的应用程序中,两个线程尝试在代码中更新相同的实体,如下所示:

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,我就不会得到重复的键异常。那么,我是否必须考虑这种并发问题?如果是这样,如果我有多个线程试图更新同一个对象,那么正确的方法是什么。

1 个答案:

答案 0 :(得分:1)

在单个节点应用程序中,当您从数据库中检索对象时,可以尝试lockSession)中的Pessimistic versioning个对象。

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

但也许你应该重新考虑一下units of work。添加lockingsynchronized块会在您的应用程序中添加高争用。当你发展一点transaction basics时,最好记住。缩短对象的寿命或Detached Object模式。使用Optimistic versioning(例如,通过添加version字段)然后处理并发修改时的错误。