안녕하세요
며칠동안 고민을 했는데 답이 안나와서 조언을 좀 얻고자 이렇게 작성 합니다 ㅠㅠ
재고 마이너스 차감 원인을 당최 모르겠습니다..
상황을 설명 드리면..
[작업실적 등록] 화면에서 작업 실적을 등록 할때 '자재 재고 테이블'에 재고 가 있을 경우 에만 작업실적을 등록 할수 있고 실적 등록을 하면
자재 재고를 UPDATE (차감) 를 해줍니다. [작업실적 등록] 은 1대의 PC에서만 하는게 아니라 여러 PC에서 등록을 합니다
A 라는 자재 재고가 0 이면 실적등록이 안되어야 하는데.. TEST 환경에서는 실적등록이 안됩니다 근데 운영 서버에서 할 경우에 간혹 0 인데도 실적 등록이 되면서
자재 재고가 (-) 수량이 됩니다.. 따로 트랜잭션 구문을 사용을 안하는데 트랜잭션이랑 상관이 있는건지요? 트랜잭션으로 했을때에도 그런 현상이 발생이 되어서..
어렵습니다 ㅠㅠ 프로그램단에서는 프로시져 만 호출 해서 프로시져에서 계산을 합니다
작업실적 등록화면 진입시 재고체크를 하나요?
그렇다면 재고가 몇개 남아 있지 않을 때
예를 들면 1개 남아 있을 때 사용자1, 사용자2가 각각 등록화면에 진입하고 등록버튼을 누르는 순간 -1씩 하니까 발생하는 거 아닐까요?
단순하지만 확실한 재고 마이너스 방지책이 있습니다.
컬럼에 양수 제약조건을 거는 겁니다.
oracle : alter table table_name add constraint check_positive CHECK (col_name >= 0);
mysql : create table table_name ( col_name int(11) unsigned check ( col_name >= 0) );
현 재고가 1 인 상황에서.
두개의 세션에서 동시에 재고를 확인합니다. 둘다 1 로 확인.
두개의 세션에서 동시에 실적을 등록합니다. 둘다 -1 차감.
두군데서 동시에 차감하니 재고가 마이너스가 됩니다.
동시성 제어가 필요합니다.
http://wiki.gurubee.net/pages/viewpage.action?pageId=26745060
제가 드린 링크를 보면
비관적 동시성 제어 방안으로 FOR UPDATE 구문을 제시합니다.
- 재고를 읽는 순간 재고에 락을 걸어버리는 것이죠.
- 이러면 먼저 선점한 사람이 등록을 마무리하기 전까지는 다른 사람은 재고 확인이 안됩니다.
낙관적 동시성?제어 방안으로 UPDATE 구문에서 확인 조건을 추가하고 있습니다.
- 재고가 등록하려는 실적보다 큰 경우에만 등록이 되도록 조건을 추가하는 방안
- 조건에 의해 등록이 실패하면 에러메시지("한 발 늦었네요")를 띄우는 방안
기타 여러가지 방법이 있을 것입니다.
- 위에 신이만든지기님께서 간단한 방안 하나 제시해 주셨네요.