У меня есть три таблицы T1, T2, T3 и четыре транзакции (A, B, C, D), которые выполняют следующие действия (это не очень важно для моего вопроса - в будущем может быть больше таблиц):
A - T1, T2 - чтение, T1, T2, T3 - запись
B - T1, T2, T3 чтение / запись
C, D - T1 - чтение, T3 чтение / запись.
У меня нет требований к производительности, поэтому я решил предотвратить одновременные транзакции:
Я создал таблицу transactionlock
с одной строкой.
Я создал интерфейс JPA:
@Repository
public interface TransactionLockRepository extends JpaRepository<TransactionLock, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select t from TransactionLock t")
TransactionLock lock();
}
Я звоню lock()
в начале каждой транзакции
@Autowired
private TransactionLockRepository lock;
@Transactional(rollbackFor = Exception.class)
@Override
public void transactionOne() {
lock.lock();
//my business code ...
}
@Transactional(rollbackFor = Exception.class)
@Override
public void transactionTwo() {
lock.lock();
//my business code ...
}
Программа, кажется, работает правильно, но я не уверен, что моя реализация абсолютно верна и не содержит ошибок.
ОБНОВЛЕНО
Если я пытаюсь синхронизировать транзакции без дополнительной таблицы, у меня возникает следующая проблема:
@Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)
public void businessLogic() {
List<TableOne> data1 = tableOneRepository.findAll();
sleep(300);
List<TableTwo> data2 = tableTwoRepository.findAll();
... Some insert/delete/update queries for tableOne, tableTwo
}
@Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)
public void cleanEvent() {
tableOneRepository.deleteAll();
tableOneRepository.flush();
tableTwoRepository.deleteAll();
tableTwoRepository.flush();
}
public void execute() {
transactions.businessLogic();
}
// In other thread
public void execute2() {
sleep(100);
transactions.cleanEvent();
}
Я хочу, чтобы первая транзакция была выполнена первой, но в этом случае у меня есть:
0) Транзакция 1 - начало
1) Транзакция 1 - чтение таблицы один
2) Транзакция 1 - сон 300
3) Транзакция 2 - начало
4) Транзакция 2 - удаление второй таблицы (не хочу!)
5) Транзакция 2 - удаление первой таблицы
6) Транзакция 1 - тупик (не могу прочитать таблицу два)
Можно ли решить эту проблему без дополнительной таблицы?