Spring - предотвращение выполнения параллельных транзакций на нескольких таблицах

У меня есть три таблицы T1, T2, T3 и четыре транзакции (A, B, C, D), которые выполняют следующие действия (это не очень важно для моего вопроса - в будущем таблиц может быть больше):

A - T1, T2 - чтение, T1, T2, T3 - запись
B - T1, T2, T3 чтение / запись
C, D - T1 - чтение, T3 чтение / запись.

У меня нет требований к производительности, поэтому я решил предотвратить одновременные транзакции:

  1. Я создал таблицу transactionlock с одной строкой.

  2. Я создал интерфейс JPA:

    @Repository
    public interface TransactionLockRepository extends JpaRepository<TransactionLock, Long> {
    
      @Lock(LockModeType.PESSIMISTIC_WRITE)
      @Query("select t from TransactionLock t")
      TransactionLock lock();
    
    }
    
  3. Я звоню 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 - тупик (не удается прочитать таблицу 2)

Можно ли решить эту проблему без дополнительной таблицы?

Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что вы просите о проверке кода. Подумайте о том, чтобы спросить о codereview.stackexchange.com (но сначала проверьте их правила и ожидания!)

Mark Rotteveel 02.05.2018 14:26

Простите! слово «обзор» - в данном случае неверно. Я просто спросил, как правильно предотвратить выполнение параллельных транзакций на нескольких таблицах.

Wi-Al 02.05.2018 14:29

Зачем изобретать велосипед? Вот для чего нужна база данных ... Вместо этого используйте правильный уровень изоляции (SERIALIZABLE) вместо того, чтобы пытаться написать свой собственный.

M. Deinum 02.05.2018 15:59

@ M.Deinum Я обновил свой первоначальный вопрос - добавил образец кода.

Wi-Al 06.05.2018 12:22
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
293
0

Другие вопросы по теме