Есть сущность с id
и каким-то другим уникальным ключом (extId
). Множество потоков (приложений) вставляют в БД сущности с незаполненным id
, но известным extId
по следующей логике:
extId
уже найден в БД, то обновить сущность новыми данными.@Transactional(propagation = REQUIRED_NEW)
public A createOrUpdate(A a) {
A b = findByExtId(a.extId, LockModeType.PESSIMISTIC_WRITE);
if (b != null) {
a.id = b.id
}
return save(a); // hibernate merge
}
Update:
@Transactional(propagation = Propagation.SUPPORTS)
public A findByExtId(final Long extId,
final LockModeType lockMode) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<A> cq = cb.createQuery(A.class);
Root<A> root = cq.from(A.class);
cq.where(cb.equal(root.get("extId"), cb.parameter(Long.class, "extId")));
TypedQuery<A> query = entityManager.createQuery(cq);
query.setParameter("extId", extId);
query.setLockMode(lockMode);
List<A> list = query.getResultList();
if (!list.isEmpty()) {
return list.get(0);
}
return null;
}
@Transactional(propagation = Propagation.SUPPORTS)
public A save(A t) {
return entityManager.merge(t);
}
Проблема в том, что данный код в редких случаях все равно вставляет сущность с одинаковым extId
несколько раз. В чем может быть причина?
База данных PostgreSQL.
Если два потока (с одним и тем же extID) примерно одновременно выполнят A b = findByExtId(a.extId, LockModeType.PESSIMISTIC_WRITE); и в БД еще нет строки с таким extID, то они оба вставят новую строчку
Потому что для обновления используется другая команда сессии.
session.update(a);
или session.merge(a);
Виртуальный выделенный сервер (VDS) становится отличным выбором
Каким образом я могу получить названия папок в assets, а также список файлов в каждой из этих папок?
Начал в своем MVP юзать интерактор) При этом Rx я не использовал) В Interactor`е я инжектил ретрофит и отправлял запрос)