IT 인터넷/Node.js
SELECT ... FOR UPDATE :: MySQL
Banjubu
2023. 6. 19. 19:12
반응형
값이 비었을 때 새로운 값을 넣는 API가 있다고 가정해요.
const [rows] = await db.query('SELECT * FROM temp')
if ((rows as ITemp[]).length < 1) {
await db.query(`INSERT INTO file (id) VALUES ('1111')`)
}
동시에 세 번 호출하면 모든 호출은 동시에 SELECT를 실행하기 때문에 다 값이 없다고 판단하고 1111을 기록해요.
$ autocannon -c 3 -a 3 http://localhost:3100/user/test
이를 방지하기 위해 SELECT 문 뒤에 FOR UPDATE를 붙여요.
const [rows] = await db.query('SELECT * FROM temp FOR UPDATE')
if ((rows as ITemp[]).length < 1) {
await db.query(`INSERT INTO file (id) VALUES ('1111')`)
}
이제 여러 번 호출해도 한 번만 기록되요.
다만, 아래와 같은 단점도 있으니 주의해야 해요. (by Bard)
- 성능 저하: SELECT FOR UPDATE로 락된 데이터는 다른 트랜잭션이 해당 데이터를 수정할 수 없기 때문에 성능이 저하될 수 있습니다.
- 데드락: 두 트랜잭션이 서로 다른 데이터를 락하여 서로를 기다리게 되는 경우 데드락이 발생할 수 있습니다. 데드락이 발생하면 두 트랜잭션 모두 실행이 중단됩니다.
- 데이터 무결성 손상: SELECT FOR UPDATE로 락된 데이터를 수정하면 데이터 무결성이 손상될 수 있습니다.
반응형
LIST