2014-12-03 9 views
2

나는 멀티 플레이 카드 게임을 가지고 있습니다. 각 게임은 4 명이합니다. 각 플레이어는 좌석 (1, 2, 3, 4)으로 지정되며, 플레이어는 게임에 참가하기 위해 클릭하고 모든 4 개의 좌석이 채워지면 게임을 시작할 수 있습니다.테이블 잠금없이 MySQL에서 동시 데이터베이스 업데이트 방지

id | status 
13 | 3 

status가 작성 좌석 수 있습니다 : 같은

는 DB에서 게임 항목이 보인다. 새 플레이어가 가입 할 때마다 증가합니다. 이제 문제가 생겼어. 때로는 2 명의 플레이어가 동시에 요청을 보내고 둘 다 동일한 좌석에 추가됩니다. 위의 예에서 두 개의 요청이 접수되고 갑자기 게임에 5 명이 등장하며 그 중 2 명이 좌석 4에 배정되었습니다.

분명히 업데이트하기 전에 4 명의 플레이어가 없는지 확인합니다.

뭔가 같은 : 논리적으로

if($row['status'] < 4){ 
    mysql_query("update games set status=status+1 where id=13"); 
} 

, 이것은 방지해야 status 지금까지 4 개 이상되는하지만, 게임에 참여 선수가 많이있는 경우, 종종 status 여러 선수가 동시에 가입 5 있기 때문에이되는 상황에있다 .

테이블 잠금을 사용하여이 문제를 방지 할 수 있지만 한 번에 하나의 행을 업데이트하기 위해 전체 테이블을 잠그지 않으려한다고 가정합니다. 동시에 50 개의 게임이 동시에 진행될 수 있습니다.

신뢰할 수있는 방법이 있어야합니다. 맞습니까?

가 DB에 규제 있도록 업데이트 문 자체에 제약을 통합 할 수

답변

2

". 업데이트 선택"당신은 또한 사용할 수

update games set status = coalesce(status, 0) + 1 
where id=13 
and coalesce(status, 0) < 4 
+0

미안하지만 그 하위 쿼리는 무엇을합니까? 이것은'update games set status = status + 1 여기서 id = 13 및 상태 <4'를 쓰는 것과 비슷하지 않습니까? – jovan

+1

@ jovan : 네, 맞습니다! 나무를 볼 수있는 나무를 볼 수 없었습니다 .... 나는 대답을 단순화 할 것입니다. – davek

1

같은

뭔가 : 업데이트

sql: 
begin(); // Need to be in a transaction. 
select status from $YOUR_TABLE where $SOMETHING for update 
code: 
if(status<4) 
    Set new status in database. 
commit(); 

선택합니다 (어디 일치하지 데이터베이스 만 단일 행) 행을 잠급니다.

+0

이 경우 행이 잠긴 동안 다른 요청이 도착하면 어떻게됩니까? 거절되었거나 대기열에 넣어 지거나 ...? – jovan

관련 문제