Sequelize.js Проблема транзакции с PostgreSQL - PullRequest
0 голосов
/ 20 ноября 2018

У меня проблема с транзакциями.

Это мой случай :

  • Я использую node.js в качестве бэкэнда с sequelize.js
  • Я использую Angular в качестве своего внешнего интерфейса
  • Я использую PostgreSQL в качестве базы данных
  • Мне нужно запустить обновление, затем вставить (в одном сервисе) и, наконец, запросить результат (в другой службе).

Итак, в первой службе я делаю UPDATE, а затем INSERT и использую транзакцию для отката, если в процессе произошла ошибка.Мой код выглядит так:

models.sequelize.transaction(t => {
    return models.table_name.update({ ... },{ where:{ ... },transaction: t })
    .then(()=>{
        return models.sequelize.query(" ... ",{ transaction:t })
        .then(result=>{
             res.status(200).send(result);
             // Everything OK and finished?
        }).catch(err=>{
              t.rollback;
              res.status(500).send(err);
        });
    }).catch(err=>{
         t.rollback;
         res.status(500).send(err);
    });
});

В angular я вызываю службу для «обновления и вставки» (см. Выше), а после ее завершения я вызываю другую службу, которая запрашивает таблицу, которую я обновляю и вставляю.

Проблема .Я заметил, что фиксация выполняется после того, как я запрашиваю мой второй сервис, первый сервис возвращает, что он завершен, но это не так.

Например, у меня есть следующий набор данных:

A    true
B    true
C    true

Я запускаю «обновление и вставка» (из углового), чтобы получить:

A    false
B    false
C    false
D    false

Когда я получаю результат этого сервиса, я немедленно запускаю (из углового) другой сервис, который запрашиваетТаблица.Но вместо получения ложных строк я получаю истинные строки без вставки:

A    true
B    true
C    true

Как будто бы ничего не случилось.

Самое смешное, что если Я удаляю транзакцию из кода, и просто делаю обновление и вставляю без начала и подтверждения (в дальнейшем), Это работает.И я получаю обновленные строки:

A    false
B    false
C    false
D    false

По понятным причинам это происходит очень быстро.Используя транзакцию, если я установлю точку прерывания и позволю завершить «обновление и вставку», служба запросов покажет мне, что мне нужно.Если я удаляю транзакцию, я получаю желаемый результат, но если что-то случается, я пропускаю откат ....

Есть подсказка, что происходит и как это исправить?

ПРИМЕЧАНИЕ: Я пытался добавить t.commit, но результат тот же.

models.sequelize.transaction(t => {
    return models.table_name.update({ ... },{ where:{ ... },transaction: t })
    .then(()=>{
        return models.sequelize.query(" ... ",{ transaction:t })
        .then(result=>{
             t.commit;// <--- COMMIT
             res.status(200).send(result);
             // Everything OK and finished?
        }).catch(err=>{
              t.rollback;
              res.status(500).send(err);
        });
    }).catch(err=>{
         t.rollback;
         res.status(500).send(err);
    });
});

1 Ответ

0 голосов
/ 21 ноября 2018

@ florin из sequelize slack ответил мне, поэтому я поместил его ответ здесь:

http://docs.sequelizejs.com/manual/tutorial/transactions.html

  1. транзакция совершается только после того, как вы обещаетевозвращение сделано.это означает, что вы должны переместить строку .then в конце, потому что sequelize.transaction также возвращает обещание, и именно тогда, когда транзакция завершена
  2. , вы можете вызвать t.rollback() вместо того, чтобы просто ссылаться на неекак t.rollback без скобок

Итак, ответ состоял в том, что я должен поместить результат в транзакцию .then как:

models.sequelize.transaction(t => {
    return models.table_name.update({ ... },{ where:{ ... },transaction: t })
    .then(()=>{
        return models.sequelize.query(" ... ",{ transaction:t })
        .catch(err=>{
              t.rollback();
              res.status(500).send(err);
        });
    }).catch(err=>{
         t.rollback();
         res.status(500).send(err);
    });
}).then(result=>{ // <-- Here goes the result
    res.status(200).send(result);
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...