Hibernate JPA更新多线程单个实体



我有消息队列,它为消息提供一些实体字段更新信息。共有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);
}
}

Hibernate Util.openSessionPostgres((每次从获取新会话

sessionFactory.openSession()

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

如果您使用sessionFactory.openSession()始终打开一个新会话,那么在更新时hibernate可能会丢失需要更新的脏字段的信息,因此会发布并更新到所有字段。

hibernate.show_sql属性设置为true将显示hibernate生成的SQLUPDATE语句。

尝试重构代码,以便在同一事务中加载实体并更新字段。不需要session.update,因为实体是管理的,在事务提交时hibernate将刷新更改并发布SQL更新。

最新更新