1. 개요
- 동시에 여러 스레드가 insert, update를 요청할 때 중복 exception없이 안정적인 트랜잭션을 보장하기 위한 여러 방법이 있다.
2. 유의사항
- 쿼리에서 for update를 활용한다면 해당 row 데이터 처리 시 lock이 걸려 select, update가 모두 불가능해지며 트랜잭션이 모두 완료되어야 다음 트랜잭션이 가능해진다.
- 다만 이러한 쿼리를 이용한 방법은 update에 국한되어 있고, insert의 경우 redis를 이용한 wait/lock이나 고립성 보장(isolation)을 해주어야 한다.
- insert, update 모두 가장 안정적이고 확실한 방법은 DB의 동시성 제어 기능을 사용하여, 서로 다른 트랜잭션이 간섭하지 못하도록 설정을 해주는 것이다.
- DB sequence의 경우 가장 확실하지만, 중간 누락이 생길 수 있으므로 이를 고려하여 활용이 필요하다.
3. 무결한 처리를 보장하는 여러가지 방법들
여러 사용자가 동시에 주문을 체결할 경우 데이터의 순차 처리를 보장할 수 있다.
1) DB Serialization
2) DB Isolaton
3) for each -> CUD 쿼리 말미에 for each를 쓰면 특정 데이터(row)를 수정하는 동안에 다른 스레드가 select, update할 수 없다(lock, wait). (수정할 경우 사용)
4) insert의 경우 DB자체적인 isolation, 고립성을 유지하기 위한 장치를 해주어야 한다(synchronized는 DBMS 수작업 쿼리/다른 프로그램을 통한 처리 등을 할 경우 안전한 트랜잭션을 보장할 수 없음)...가장 확실한 것은 DB lock.
5) DB sequence는 도중에 누락이 발생할 경우 연속되지 않는 PK가 발생할 수 있으므로, 중간 누락이 상관없다면 가장 중복을 방지할 수 있는 확실한 방법이다.
4. 참고자료
DB Serializable : https://www.google.com/search?q=db+serializable&sca_esv=ede45a10bafd6a14&sxsrf=ADLYWILGXRXxCcRslvEAiQ7j4Glc7_dXqQ%3A1728047214575&source=hp&ei=buj_ZtTNH83g2roP5e60iQI&iflsig=AL9hbdgAAAAAZv_2fniCQuH4HwuPVxhualo10Moqnddj&oq=db+serial&gs_lp=Egdnd3Mtd2l6IglkYiBzZXJpYWwqAggBMgUQABiABDIFEAAYgAQyBRAAGIAEMgQQABgeMgQQABgeMgQQABgeMgQQABgeMgQQABgeMgYQABgeGA8yBhAAGAUYHkiNGVAAWLkPcAB4AJABAJgB3AKgAdMMqgEHMC41LjIuMbgBA8gBAPgBAZgCCKACkg3CAgQQIxgnwgINEC4YgAQY0QMYxwEYCsICERAuGIAEGLEDGNEDGIMBGMcBwgIIEAAYgAQYsQPCAgsQABiABBixAxiDAcICBBAAGAPCAgsQLhiABBjRAxjHAcICDhAuGIAEGLEDGNEDGMcBmAMAkgcHMC40LjMuMaAH4Tc&sclient=gws-wiz
for update : https://dololak.tistory.com/446, https://velog.io/@jisulog/MySQL-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EA%B3%BC-SELECT-FOR-UPDATE%EB%AC%B8
MSSQL의 insert 동시성 제어 : https://velog.io/@jonghne/Mybatis-insert%EC%8B%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0%EA%B0%80-%EC%9D%B4%EB%AF%B8-%EC%A1%B4%EC%9E%AC%ED%95%98%EB%A9%B4-update-%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-upsert%EB%AC%B8
sync의 한계 : https://mudchobo.tistory.com/280
DB Lock : https://ohksj77.tistory.com/251