2009-07-08 2 views
1

여러 작업자가 행을 SELECT하고 UPDAT하고 있습니다.MYSQL 행이 두 번 이상 업데이트되지 않도록하려면 어떻게해야합니까?

ID 상태 10 새로운 새로운 11 12 13 세 이전

작업자 '새로운'의 행을 선택하고, '이전'로 상태를 갱신한다. 두 명의 작업자가 같은 행을 동시에 선택하면 어떻게됩니까? worker1이 새 행을 선택하고 worker 1이 상태를 업데이트하기 전에 worker2가 동일한 행을 선택한다는 의미입니까?

하나의 쿼리에서 SELECT 및 UPDATE를 수행해야합니까 아니면 다른 방법이 있습니까?

답변

2

읽기 전에 테이블을 잠글 수 있으며 쓰기 후에 잠금을 해제 할 수 있습니다. 이것은 동시에 두 명의 작업자가 동일한 레코드를 업데이트 할 기회를 제거합니다.

http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html

+0

읽기 방지 잠금합니까/SELECT? 내가 여전히 선택할 수 있다면, 나는 아래의 @daremon이라는 개념을 사용할 것입니다. –

+1

쓰기 잠금을 수행하면 읽기 또는 쓰기를 시도 할 때 다른 모든 세션이 차단됩니다. – Pro777

0

데이터베이스 스토리지 엔진 (이노, MYISAM 등)에 따라, 당신은 사람이 그것을 modifing에있는 동안 테이블을 잠글 수 있습니다. 그런 다음 동일한 테이블에 유사 행동을 유지합니다.

0

PHP 논리에 조건을 넣어 잠금을 암시 할 수 있습니까? 두 번째 사용자가 업데이트를 수행하지 못하게하는 행에 상태 속성을 설정하는 것과 같습니다. 이렇게하려면 행이 잠기지 않았는지 확인하기 위해 데이터베이스를 쿼리해야 할 수도 있습니다.

+0

업데이트 직전에 데이터베이스를 쿼리하면 동시성 보호 기능이 좋지 않습니다. 이는 여전히 업데이트 될 수 있습니다. –

3

당신은 LOCK 테이블을 사용할 수 있지만 가끔은 (의사 코드) 다음과 같은 솔루션을 선호 :

// get 1 new row 
$sql = "select * from table where status='new' limit 0, 1"; 
$row = mysql_query($sql); 

// update it to old while making sure no one else has done that 
$sql = "update table set status='old' where status='new' and id=row[id]"; 
mysql_query($sql); 

// check 
if (mysql_affected_rows() == 1) 
    // status was changed 
else 
    // failed - someone else did it 
+0

코드에서 수행 한 작업도 내가 한 작업입니다. 나는 그것이 가장 효율적이라고 생각하지 않지만 간단하고 효과적이다. 고맙습니다! –

관련 문제