[ORM] ๐ Sequelize - Transaction ๋ฌธ๋ฒ
์ ํํ์ต
Sequelize Transaction
Sequelize๋ transaction์ ์ฌ์ฉํ๊ธฐ ์ํด ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์ง์ํ๋ค.
- Unmanaged Transactions : Unmanaged transactions๋ ์ฌ์ฉ์๊ฐ ์ปค๋ฐ๊ณผ ๋กค๋ฐฑ์ ์ง์ ์์ฑํด์ผ ํ๋ค.
- Managed Transactions : Managed transactions๋ Sequelize๊ฐ ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋ ์๋์ผ๋ก ํธ๋์ญ์ ์ ๋กค๋ฐฑํด์ฃผ๋ฉฐ, ๋ฐ๋์ ๊ฒฝ์ฐ์๋ ์๋์ผ๋ก ์ปค๋ฐ์ ํด์ค๋ค.
๋ค์ ORM ์ฝ๋๊ฐ ์๋ค๊ณ ๊ฐ์ ํ์.
3๊ฐ์ ์ฟผ๋ฆฌ๋ ๋ฐ๋์ ๋ชจ๋ ์ฑ๊ณตํ๊ฑฐ๋ ์คํจํด์ผ ํ๋ค. ์ค๊ฐ์ ์ด๋ค๊ฑด ์ฑ๊ณตํ๊ณ ์ด๋ค๊ฑด ์คํจ๋์ฑ๋ก ์กฐ์๋๋ฉด ํฌ๋ํฐ ๋ฌธ์ ๊ฐ ๋๋ค๊ณ ํ์.
const success = await Auction.findOne({
where: { GoodId: good.id },
order: [['bid', 'DESC']],
});
await Good.update(
{ SoldId: success.UserId },
{ where: { id: good.id } },
);
await User.update(
{ money: sequelize.literal(`money - ${success.bid}`) },
{ where: { id: success.UserId } },
);
Unmanaged Transactions
//* ํธ๋์ญ์
์ค์
const t = await sequelize.transaction();
// try catch๋ก ๋ฌถ์ !!
try {
const success = await Auction.findOne({
where: { GoodId: good.id },
order: [['bid', 'DESC']],
transaction: t, // ์ด ์ฟผ๋ฆฌ๋ฅผ ํธ๋์ญ์
์ฒ๋ฆฌ
});
await Good.update(
{ SoldId: success.UserId },
{
where: { id: good.id },
transaction: t, // ์ด ์ฟผ๋ฆฌ๋ฅผ ํธ๋์ญ์
์ฒ๋ฆฌ
},
);
await User.update(
{ money: sequelize.literal(`money - ${success.bid}`) },
{
where: { id: success.UserId },
transaction: t, // ์ด ์ฟผ๋ฆฌ๋ฅผ ํธ๋์ญ์
์ฒ๋ฆฌ
},
);
await t.commit(); // ํธ๋์ญ์
๋ฌธ์ ์์ผ๋ฉด ์ปค๋ฐ
} catch (err) {
await t.rollback(); // ์ค๊ฐ์ failed ๋๋ฉด ํธ๋์ญ์
๋กค๋ฐฑ
}
unmanaged transaction์ ์์ ๋ณด์ด๋ ์ฝ๋์ ๊ฐ์ด ๊ฐ๋ฐ์๊ฐ ์ผ์ผํ commit ๊ณผ rollback์ ์์น๋ฅผ ์ง์ ํด๋๋ ๋ฐฉ๋ฒ์ด๋ค.
์ฝ๋๊ฐ ๋ฌธ์ ์์ด ์คํ์ด ๋์๋ค๋ฉด try์ ๋ง์ง๋ง ๋ถ๋ถ์์ transaction์ ์ปค๋ฐํ๋ค.
๋ง์ฝ ์ฝ๋ ์ค๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ฉด catch ๋ถ๋ถ์์ transaction์ ๋กค๋ฐฑํ ํ ์๋ฌ ๋ก๊ทธ๋ฅผ ๋ฐ์์ํจ๋ค.
Managed Transactions
// try catch๋ก ๋ฌถ์ !!
try {
//* ํธ๋์ญ์
์ค์
await sequelize.transaction(async (t) => {
const success = await Auction.findOne({
where: { GoodId: good.id },
order: [['bid', 'DESC']],
transaction: t, // ์ด ์ฟผ๋ฆฌ๋ฅผ ํธ๋์ญ์
์ฒ๋ฆฌ
});
await Good.update(
{ SoldId: success.UserId },
{
where: { id: good.id },
transaction: t, // ์ด ์ฟผ๋ฆฌ๋ฅผ ํธ๋์ญ์
์ฒ๋ฆฌ
},
);
await User.update(
{ money: sequelize.literal(`money - ${success.bid}`) },
{
where: { id: success.UserId },
transaction: t, // ์ด ์ฟผ๋ฆฌ๋ฅผ ํธ๋์ญ์
์ฒ๋ฆฌ
},
);
});
// ํธ๋์ญ์
๋ฌธ์ ์์ผ๋ฉด ์์์ ์๋์ผ๋ก ์ปค๋ฐ
} catch (err) {
// ์ค๊ฐ์ failed ๋๋ฉด ์์์ ์๋์ผ๋ก ํธ๋์ญ์
๋กค๋ฐฑ
}
Managed trasaction์ Unamanaged Transaction๊ณผ ์ ์ฌํ์ง๋ง,
๊ฐ๋ฐ์๊ฐ commit๊ณผ rollback์ ๋ฐ๋ก ๋ช ์ํ์ง ์์๋ ๋๋ค๋ ์ฐจ์ด์ ์ด ์๋ค.
๊ธฐ๋ฅ์ด ๋ฌธ์ ์์ด ์งํ์ด ๋๋ค๋ฉด ์ฝ๋ฐฑํจ์ ๋ง์ง๋ง ๋ถ๋ถ์์ commit์ ์๋์ผ๋ก ์คํํ๋ฉฐ, error๊ฐ ๋ฐ์ํ๋ฉด ์๋์ผ๋ก rollback์ ํด์ค๋ค.
transaction์ ์ฌ์ฉํ ๋ ์ ์ํด์ผ ํ ์ ์ try catch์ ๋ฒ์๋ฅผ ์ ์ดํด๋ณด๋ ๊ฒ์ด๋ค.
๋ง์ฝ managed transaction์ ์ฌ์ฉํ๋ฉด์ try ๋ฒ์ ๋ฐ์์ throw Error๋ฅผ ๋์ง๋ค๋ฉด, catch์์ ์๋ฌ๋ฅผ ์ก์ง ๋ชปํด ๋กค๋ฐฑ์ด ์คํ๋์ง ์์ ์ ์๋ค.
๊ทธ๋ฌ๋ฏ๋ก ํญ์ ์ํฉ์ ๋ง์ถฐ์ try catch์ ๋ฒ์๋ฅผ ์ ์ ํํด์ผ ํ๊ณ , ๊ฑฐ๊ธฐ์ ๋ง๋ transaction ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ผ ํ๋ค.
์ฝ๋ ๋ก์ง์ด ๋ณต์กํ ๊ฒฝ์ฐ์๋,
์ด๋์ ์ปค๋ฐ๊ณผ ๋กค๋ฐฑ์ด ์ผ์ด๋๋ ์ง ์ฝ๊ฒ ์๊ธฐ ์ํด unmanaged transaction์ ์ฌ์ฉํ์ฌ ๊ฐ๋ ์ฑ์ ๋์ด๋๊ฑธ ์ถ์ฒํ๋ ๋ฐ์ด๋ค
Reference
https://jeonghwan-kim.github.io/2016/07/13/sequelize-transaction.html
https://avengersrhydon1121.tistory.com/224