회고/Error Handling

Sequelize - Transaction Error

yhjs1211 2023. 7. 31. 23:16

발단

Error: commit has been called on this transaction(335a1835-ea4c-4b83-a7ed-9861fe1321c6), you can no longer use it.

 

상황으로 말하자면 트랜잭션 커밋을 시도하려 했으나 이미 커밋이 호출이 되어있는 상황이기에 다시 사용할 수 없다는 오류였다.

StackOverFlow에서 열심히 서치를 해본 결과, 세부적인 내용은 알아볼 수 없었으나 forEach 문에 대한 문제라는 것을 알 수 있었다.

JSON.parse(timetable).forEach( async (id) => {
    const instance = await Timetable.create({
        time : id,
        date,
        showId : Number(showId),
        isFilled : false
    },{
        include:[Seat],
        transaction
    });
    timeArray.push(instance);
    
    	// ...

 

🔥 - 예상

 

forEach 문 내부 콜백함수에 async 를 붙여주었음에도 내부의 트랜잭션에 대한 await 처리가 정상적으로 이루어 지지 않았고, 그랬기 때문에 한번의 for문을 돌고 2번째 돌때 Promise 가 fulfilled 상태가 아닌 Pending 상태에 남아있어서 커밋을 할수 없다 란 오류를 발생시킨게 아닐까 싶다.

for(let i=0; i<JSON.parse(timetable).length; i++){
    const instance = await Timetable.create({
        time : arrayOfTimetable[i],
        date,
        showId : Number(showId),
        isFilled : false
    },{
        include:[Seat],
        transaction
    });
    timeArray.push(instance);
    
    	// ...

 

결론적으론 위의 코드와 같이 forEach 문이 아닌 일반 for문으로 변경해주고 실행을 해보니 정상적으로 처리됨을 확인할 수 있었다.

 

비동기 처리에 대해 forEach가 어떤 관여를 하는지 정확히 알아봐야 할 것 같다.