2012-05-09 3 views
0

여러 상담원이 하나씩 테이블에서 고객을로드하는 C#에서 콜 센터 프로그램을 작성하고 있습니다. 둘 이상의 에이전트가 동일한 고객을로드하지 못하게하기 위해 테이블에 행이 잠겨 있음을 나타내는 새 필드를 추가했습니다. 행을 선택하면 해당 행을 업데이트하고 해당 행을 선택한 에이전트의 ID로 잠금 필드를 설정합니다. 하지만 문제는 내가 행을 선택하고 잠그는 동안, 다른 에이전트가 아직 잠겨 있지 않기 때문에 동일한 행을 선택할 수 있습니다! 이 상황을 처리 할 수있는 방법이 있습니까? 데이터베이스는 MySQL의 5/이노다른 세션에서 UPDATE가 발생하기 전에 행을 SELECT하는 것을 방지하는 방법

+0

어떤 기준에 따라 '테이블에서 하나씩'을 씁니까? 가장 오랜 시간 동안 탁자에 있던 사람? – MiMo

답변

1

당신은 에이전트 당 1 개 프로파일을 잠글 수 있습니다 가정입니다 : 내가 업데이트를 실행하기 전에 내가 ID를 선택해야

--Check for no lock 
UPDATE T SET LockField = 'abc' WHERE ProfileId = 1 AND LockField IS NULL; 

--Check to see if we updated anything. 
--If not, we can't show this row because someone else has it locked 
SELECT ROW_COUNT(); 

...

UPDATE in 1 명령문을 수행하면 그렇지 않습니다. 아주 쉽게

--Check for no lock 
UPDATE T SET LockField = 'abc' WHERE ProfileId = (
    SELECT ProfileId FROM T WHERE LockField IS NULL LIMIT 1 
); 

--Check to see what we updated 
SELECT * FROM T WHERE LockField = 'abc'; 

작품 :처럼하지만 뭔가 - 우리는 MySQL의 구문의 내 지식 지난 조금 있어요. 당신은 좀 더 복잡 할 경우

(또는 MySQL의 서브 쿼리를 지원하지 않습니다), 당신은 ... FOR UPDATE SELECT와 업데이트 잠금을 사용할 수 있습니다

START TRANSACTION; 

--Put an update lock on the row till the xaction ends 
--any other SELECT wanting an update lock will block until we're out of the xaction 
SELECT @id = ID FROM T WHERE LockField IS NULL LIMIT 1 FOR UPDATE; 

UPDATE T SET LockField = 'abc' WHERE ID = @id; 

COMMIT TRANSACTION; 
관련 문제