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;

    }
    ...

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

4

1 回答 1

1

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

更多关于锁定。还有一点关于休眠并发的建议。

但也许你应该重新考虑一下units of work。添加lockingsynchronized 阻止将在您的应用程序上添加高争用。当您开发一些交易基础知识时,最好记住这一点。Detached Object缩短对象或模式的寿命。使用Optimistic versioning(例如通过添加version字段)然后处理并发修改的错误。

于 2013-03-04T22:16:02.230 回答