async/awaitで書くことも増えてきたので、SequelizeのTransactionもPromise脱却したい!ということで改めて調べてみた。
AsIs
(targetId) => {
sequelize.transaction((t) => {
return User.destory({
where: {
id: targetId
},
transaction: t
}).then((result) => {
// Transaction has been committed
}).catch((error) => {
// Transaction has been rolled back
});
});
今までやってたのがこんな感じのPromiseチェイン。Sequelize公式もこんな書き方を紹介してるけど、チェインが長くなるとどこでロールバックされるのかパッと見分からないと感じてた。
そこで、以下のようにTransactionのコールバック内でasync/awaitにしてみたりして。。。
sequelize.transaction(async (t) => {
await User.destory({
where: {
id: targetId
},
transaction: t
});
});
これで失敗すれば自動的にロールバックされる、らしいのだけども個人的にはやっぱり把握しずらい。
ToBe
sequelize.transaction() は transactionオブジェクトをreturnするで、そのままasync/awaitの記法で使える。
async (targetId) => {
const t = await sequelize.transaction();
try {
const result = await User.destroy({
where: {
id: targetId
},
transaction: t
});
await t.commit(); // Transaction has been committed
return result;
} catch(error) {
await t.rollback(); // Transaction has been rolled back
return error;
}
処理の成否は明示的に commit / rollbackを実行する必要があるので、手間と感じる人もいるだろけど、自分的にはコードが読みやすくなるのでこっちのが好み。