hibernatejpa更新多线程单实体

gj3fmq9x  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(274)

我有一个消息队列,它提供一些实体字段更新信息的消息。有10个线程处理队列中的消息。
例如
第一个线程处理消息,此线程应更新id为123的实体中的字段a。
第二个线程处理另一条消息,这个线程应该同时更新id为123的实体中的字段b。
有时更新后数据库不包含一些更新的字段。
一些更新程序:

someService.updateEntityFieldA(entityId, newFieldValue);

一些服务:

public Optional<Entity> findById(String entityId) {
    return Optional.ofNullable(new DBWorker().findOne(Entity.class, entityId));
}

public void updateEntityFieldA(String entityId, String newFieldValue) {
    findById(entityId).ifPresent(entity -> {
        entity.setFieldA(newFieldValue);
        new DBWorker().update(entity);
    });
}

数据库工作者:

public <T> T findOne(final Class<T> type, Serializable entityId) {
    T findObj;

    try (Session session = HibernateUtil.openSessionPostgres()) {
        findObj = session.get(type, entityId);
    } catch (Exception e) {
        throw new HibernateException("database error. " + e.getMessage(), e);
    }

    return findObj;
}

public void update(Object entity) {
    try (Session session = HibernateUtil.openSessionPostgres()) {
        session.beginTransaction();
        session.update(entity);
        session.getTransaction().commit();
    } catch (Exception e) {
        throw new HibernateException("database error. " + e.getMessage(), e);
    }
}

opensessionpostgres()每次从

sessionFactory.openSession()

有没有可能在没有线程锁/乐观锁和悲观锁的情况下实现这样的逻辑?

yc0p9oo0

yc0p9oo01#

如果你使用 sessionFactory.openSession() 要始终打开一个新会话,在更新时hibernate可能会丢失有关需要更新的脏字段的信息,因此问题和更新到所有字段。
设置 hibernate.show_sql 属性到 true 将向您显示sql UPDATE 由hibernate生成的语句。
尝试重构代码,以便在同一事务中加载实体并更新字段。一 session.update 不需要,因为实体是托管的,在事务提交时hibernate将刷新更改并发出sql更新。

相关问题