为了使用乐观锁,首先需要一个version 列。
现在,如果批量更新语句不增加 version 列,则可能会发生丢失更新异常:
现在,为了避免丢失更新,您只需增加 version 列。
您可以使用任何类型的查询来做到这一点。
JPQL
int updateCount = entityManager
.createQuery(
"update Post " +
"set " +
" status = :newStatus," +
" version = version + 1 " +
"where " +
" status = :oldStatus and " +
" lower(title) like :pattern")
.setParameter("oldStatus", PostStatus.PENDING)
.setParameter("newStatus", PostStatus.SPAM)
.setParameter("pattern", "%spam%")
.executeUpdate();
标准 API
CriteriaBuilder builder = entityManager
.getCriteriaBuilder();
CriteriaUpdate<Post> update = builder
.createCriteriaUpdate(Post.class);
Root<Post> root = update.from(Post.class);
Expression<Boolean> wherePredicate = builder
.and(
builder.equal(
root.get("status"),
PostStatus.PENDING
),
builder.like(
builder.lower(root.get("title")),
"%spam%"
)
);
Path<Short> versionPath = root.get("version");
Expression<Short> incrementVersion = builder
.sum((short) 1, versionPath);
update
.set(root.get("status"), PostStatus.SPAM)
.set(versionPath, incrementVersion)
.where(wherePredicate);
int updateCount = entityManager
.createQuery(update)
.executeUpdate();
原生 SQL
UPDATE post
SET
status = 2,
version = version + 1
WHERE
status = 0 AND
lower(title) LIKE '%spam%'
一旦您增加了version 列,将在加载由批量语句更新的实体的先前版本的并发事务中防止丢失更新: