2009-06-18 3 views
5

필자는 PDO와 MySQL의 내부 동작에 100 % 미치지 않는다는 것을 인정할 것입니다. 그래서 제 질문을 명확하게하기위한 예제를 드리겠습니다.MySQL이 트랜잭션을 끝내기 전까지 PHP를 기다리게하는 방법이 있습니까?

나는 PHP와 데이터베이스를 배우는 재미있는 방법이라고 생각하기 때문에 다소 기초적인 브라우저 기반 전략 게임을 만들고 있습니다. 나는 예기치 않은 버그를 발견했을 때 전투 스크립트를 버그 테스트했습니다. 나는 Cron Jobs를 사용하여 매분마다 다음과 같은 스크립트를 호출합니다.

$ sql = "SELECT army_id FROM arrivalarmy WHERE arrival = 0;"; 기본 계산은 (군대를 방어 대 군대를 공격) 완료

foreach($dbh->query($sql) as $row) 
    { 

     battleEngine($row["army_id"]); 

    } 

, 데이터베이스의 여섯 개 테이블이 업데이트됩니다. 내가 직면 한 문제는 동일한 순간에 같은 대상에서 몇 차례 공격을 할 때마다 그 중 하나가 오래된 데이터베이스 정보를 가져옵니다 (극단적 인 경우 공격 # 10은 공격 # 5와 동일한 테이블을 가져옴) .

스크립트가 데이터베이스보다 빠르기 때문에 이런 현상이 발생한다고 생각하십니까? 다음 $ 행을 사용하여 함수를 반복하기 전에 PHP가 모든 관련 정보를 얻을 때까지 기다리는 방법이 있습니까?

EDIT : Emil이 맞을 수도 있습니다. 필자는 PDO가 beginTransaction()과 commit() 사이에 여러 문장을 전달하기에 충분히 길게 열려있을 수 없기 때문에 확신 할 수 없습니다. 그러나 InnoDB를 "REPEATABLE READ"와 함께 사용하고 있기 때문에 더러운 읽기가 이상하게 보입니다. 어떤 인터넷 검색은 REPEATABLE READ가 더티 읽기를 불가능하게 만들 것을 제안합니다. 잠시 동안 자신을 어떻게 죽일지 고민하고 나서는 대신 해킹을 선택했습니다. 지금은 특수 값에 대한 UPDATE를 내 스크립트 상단에 배치하고 다른 하나는 큰 배치 (약 6 개의 UPDATE 문) 맨 아래에 배치합니다. 함수를 실행하기 전에 특별한 값이 0으로 설정되어 있는지 검사하는 while() - 루프를 작성했습니다. 그렇지 않은 경우 0.01 초 동안 휴면하고 다시 시도합니다. 출력을 살펴보면, while 루프는 평균 2 회 반복되므로 실제로 작동 중일 수 있습니다. 아직 실패하지는 않았지만 피크 시간이 아니기 때문일 수 있습니다. 나는 내일 정기적 인 간격으로 다시 시도 할 것이다. 나는이 모든 것에 대해 아무도 신경 쓰지 않는다는 것을 알고 있지만, 나는이 업데이트를 방금 경우에 대비해야한다고 느꼈다. = P

답변

1

PHP가 그냥 기다리면 많은 수의 크론 작업이 쌓일 것입니다.

당신이 이 실제로 일 때, 주어진 순간에 하나의 스크립트 인스턴스 만 실행되도록하려면 anachron과 같은 것을 사용하는 것이 좋습니다. 또한 다음과 같은 것을 할 수 있습니다 :

<?php 

    if (file_exists('/tmp/myscriptlock')) exit(); 
    touch('/tmp/myscriptlock'); 

    // do your stuff 

    unlink('/tmp/myscriptlock'); 
+0

잘못된 서식 지정을 위해 srry – Evert

+1

작업과 연결이 끊어지면 잠금이 자동으로 해제되는 방식으로 MySQL 잠금을 사용하는 것이 좋습니다. http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock –

1

"더티 읽기"라고하는 것은 무엇입니까? InnoDB를 사용하고 isolation level을 직렬화 가능으로 설정하십시오.

$dbh->beginTransaction(); 
// run queries 
$dbh->commit(); 
관련 문제