Spring @Transactional последовательно откатывает транзакцию при исключении - PullRequest
0 голосов
/ 26 сентября 2018

Ладно, ребята.Я прочитал довольно много документов.И в конце концов я пойму, почему это происходит.

Как и многие другие люди, у нас есть служба, взаимодействующая с оракулом.Это довольно стандартная настройка

@Service
public class DaoService {

    private JdbcTemplate jdbcTemplate;

    private SimpleJdbcInsert insertA;
    private SimpleJdbcInsert insertB;
    private SimpleJdbcInsert insertC;

    @Autowired
    public Dao(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        // Assume all Inserts are initialized
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertStuff(Stuff stuff) {
         insertA.execute(stuff.A);
         // Suppose a connection failed here
         insertB.executeBatch(stuff.B);
         insertC.executeBatch(stuff.C);
}

Теперь здесь кроется наша проблема.Для 99% откатов все в порядке.

Когда по неизвестным причинам соединение закрывается, возникают наши проблемы.Сообщение об исключении:

 TransactionSystemException: Could not roll back JDBC transaction;
     nested exception is java.sql.SQLException: "The connection is closed"

Видите, оно пытается выполнить откат, как положено.Но проблема в том, что штука A, задерживающаяся в БД, будет вещи B, а вещи C нет.Это происходит только как 1% времени.(ака, иногда, несмотря на ошибку отката, в DB не будет «мелочей».

Я понимаю, что-то не так? Я думал, что пружина фиксирует коммит только в конце успешной транзакции? У кого-нибудь есть идеи о том, какЯ могу остановить эти частичные коммиты, несмотря на то, что они делают в @Transactional?

ps за то, что это стоит. Автокоммит по умолчанию включен. Однако я читал, что это не учитывается, когда что-то @ Transactional

Ответы [ 3 ]

0 голосов
/ 26 сентября 2018

Из Руководства разработчика базы данных JDBC :

Если режим автоматической фиксации отключен и вы закрываете соединение без явной фиксации или отката последних изменений, тогдазапускается неявная операция COMMIT.

Возможно, это тот случай, когда вы сталкиваетесь.

0 голосов
/ 26 сентября 2018

попробуйте это:

@Transactional(propagation = Propagation.REQUIRES_NEW)

надеюсь, что это будет работать

0 голосов
/ 26 сентября 2018

Согласно этому ответу , Spring предлагает вам только интерфейс для диспетчера транзакций, и реализация может отличаться.Однако большинство реализаций менеджера транзакций отключают автокоммит во время вызова @Transactional, а затем возвращают его в предыдущее состояние после фиксации.

При этом в некоторых базах данных существуют способы выполнения автономных транзакций внутри внешней транзакции, которыеможет не отображаться в вашем приложении или в Spring.Я знаю, что Oracle позволяет это.Вы проверили все триггеры на столах?Я работал над одним приложением, у которого был триггер аудита, который заставлял бы потерянные данные в некоторых таблицах в подобных ситуациях.Можете ли вы сказать нам, какую базу данных вы используете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...