...
선행학습
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
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.