Сколько транзакций и записей в БД будет?
От: Aleksei_Lekomtsev  
Дата: 05.10.23 11:11
Оценка:
@Component
public class Dao {

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void storeAll(List<Integer> list) throws Exception {
        for (var i : list) {
            store(i);
        }
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void store(Integer i) throws Exception {
        if (i == 3) {
            throw new SQLException();
        } else {
            // добавить запись в таблицу
        }
    }
}


Есть несколько предположений:
1 Будет 4 транзакции
2 Будет 0 записей, так как при срабатывании SQLException оно пробросится во внешнюю транзакцию(storeAll) и так как там оно не отлавливается, то внешняя транзакция(storeAll) сделает rollback
3 Будет 2 записи(1, 2), так как вложенная транзакция(store) при i == 3 не сделает rollback так как по умолчанию — The checked exception does not trigger a rollback of the transaction и внешняя транзакция (storeAll) тоже не сделает rollback по такой же причине

П.C. Правильно я понимаю что для store нельзя использовать private модификатор, так как proxy объект(который создается из-за Transactional annotation) не сможет к этому методу обраться?(т.е. там не reflection?)
Отредактировано 05.10.2023 11:14 Aleksei_Lekomtsev . Предыдущая версия .
Re: Сколько транзакций и записей в БД будет?
От: rosencrantz США  
Дата: 05.10.23 11:28
Оценка: 1 (1) +1
Здравствуйте, Aleksei_Lekomtsev, Вы писали:


A_L>Есть несколько предположений:

A_L>1 Будет 4 транзакции

Будет 1 транзакция. Вызовы store из storeAll буду дёргать непроксированный метод store. Чтобы дёргать проксированный, нужно объекту Dao заинжектить ссылку на объект Dao. Тогда внутри this будет ссылаться на чистый объект, а ссылка на Dao — на проксированный.

A_L>2 Будет 0 записей, так как при срабатывании SQLException оно пробросится во внешнюю транзакцию(storeAll) и так как там оно не отлавливается, то внешняя транзакция(storeAll) сделает rollback


Да

A_L>3 Будет 2 записи(1, 2), так как вложенная транзакция(store) при i == 3 не сделает rollback так как по умолчанию — The checked exception does not trigger a rollback of the transaction и внешняя транзакция (storeAll) тоже не сделает rollback по такой же причине


Нет
Re: Сколько транзакций и записей в БД будет?
От: vsb Казахстан  
Дата: 05.10.23 11:36
Оценка: 3 (1)
Здравствуйте, Aleksei_Lekomtsev, Вы писали:

A_L>Сколько транзакций и записей в БД будет?


Те, которые успели закоммититься — останутся. Остальные — нет. Отката уже закоммиченных вложенных транзакций не будет.

A_L>П.C. Правильно я понимаю что для store нельзя использовать private модификатор, так как proxy объект(который создается из-за Transactional annotation) не сможет к этому методу обраться?(т.е. там не reflection?)


Твой код скорей всего вообще работать не будет. То бишь при вызове store эта аннотация не будет приниматься во внимание. Чтобы он работал, тебе надо сделать что-то вроде

@Component
public class Dao {

    @Autowired Dao self;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void storeAll(List<Integer> list) throws Exception {
        for (var i : list) {
            self.store(i);
        }
    }


Ну или вынести метод store в отдельный класс.
Отредактировано 05.10.2023 11:37 vsb . Предыдущая версия .
Re[2]: Сколько транзакций и записей в БД будет?
От: Aleksei_Lekomtsev  
Дата: 05.10.23 11:44
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, Aleksei_Lekomtsev, Вы писали:


A_L>>Сколько транзакций и записей в БД будет?


vsb>Те, которые успели закоммититься — останутся. Остальные — нет. Отката уже закоммиченных вложенных транзакций не будет.


A_L>>П.C. Правильно я понимаю что для store нельзя использовать private модификатор, так как proxy объект(который создается из-за Transactional annotation) не сможет к этому методу обраться?(т.е. там не reflection?)


vsb>Твой код скорей всего вообще работать не будет. То бишь при вызове store эта аннотация не будет приниматься во внимание. Чтобы он работал, тебе надо сделать что-то вроде


vsb>
vsb>@Component
vsb>public class Dao {

vsb>    @Autowired Dao self;

vsb>    @Transactional(propagation = Propagation.REQUIRES_NEW)
vsb>    public void storeAll(List<Integer> list) throws Exception {
vsb>        for (var i : list) {
vsb>            self.store(i);
vsb>        }
vsb>    }
vsb>


vsb>Ну или вынести метод store в отдельный класс.


@Component
public class Dao {

    @Autowired Dao self;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void storeAll(List<Integer> list) throws Exception {
        for (var i : list) {
            self.store(i);
        }
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void store(Integer i) throws Exception {
        if (i == 3) {
            throw new SQLException();
        } else {
            // добавить запись в таблицу
        }
    }
}

Т.е. если правильно понял при таком варианте — будет 4 транзакции(1 для storeAll и 3 для store) и 2 записи в БД — 1 и 2?
А rollback для транзакций не срабатывает потому что SQLException?
Re[3]: Сколько транзакций и записей в БД будет?
От: Gt_  
Дата: 05.10.23 12:13
Оценка:
A_L>Т.е. если правильно понял при таком варианте — будет 4 транзакции(1 для storeAll и 3 для store) и 2 записи в БД — 1 и 2?
A_L>А rollback для транзакций не срабатывает потому что SQLException?

нет, будет 1 транзакция и она будет отролбечина. причина — ошибка в коде. вторая анотация с REQUIRES_NEW не сработает. store метод надо выносить в отдельный класс. тогда сработают обе аннотации. rosencrantz выше все разжувал.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.