2011-08-11 2 views
1

두 데이터베이스 사이에서 데이터를 동기화하는 스크립트를 사용하고 있습니다 (호스트 된 도메인에 로컬로). 누군가가 CMS에서 로그 아웃 할 때 동기화가 발생했습니다. 유감스럽게도, 두 번의 로그 아웃이 발생하여 동기화 스크립트가 두 번 실행되는 경우를 보았습니다. 그것은 변경하려는 시스템의 일부가 아니지만 이미 실행중인 경우 해당 스크립트 (sync.php)를 실행하지 못하게하는 쉬운 방법을 기대하고있었습니다.PHP 스크립트가 동시에 실행되지 않도록하려면 어떻게합니까?

은 그 테스트 스크립트를 내놓았다 한 : 같은 시간에 (내가 두 번 스크립트를 실행할 수 있습니다, 이상한 외국인 이유로

function transactionBegun() 
    { 
     $_ResultSet = $this->query("SELECT @TransactionBegun AS TransactionBegun")->fetch_all(true); 

     return $_ResultSet[ 'TransactionBegun' ]; 
    } 

:

$db = new DB_Mysql(); 

if ($db->transactionBegun() == "0") 
{ 
    $_Continue = true; 

    $_Continue = $_Continue && $db->squery("START TRANSACTION"); 

    $_Continue = $_Continue && $db->squery("SET @TransactionBegun = true"); 

    sleep(10); 

    $_Continue = $_Continue && $db->squery("INSERT INTO tbConfiguration VALUES(NOW(), NOW())"); 

    $_Continue = $_Continue && $db->squery("SET @TransactionBegun = false"); 

    if ($_Continue) 
    { 
     $db->query("COMMIT"); 
    } else { 
     $db->query("ROLLBACK"); 
    } 
} 

transactionBegun 방법은 구성) 두 항목 모두 만들어집니다.

어떤 아이디어 ??

편집 : 나는 내가 mysql_pconnect()를 사용하고 있고 서버가 Windows 시스템에서 호스팅되는 것을 언급하는 것을 잊었다. 전체 시스템은 태블릿 PC를 사용하는 금전 등록기입니다. 서버에 액세스하는 유일한 클라이언트는 "localhost"입니다.

+0

@Variables는 연결에만 존재하며 전역 적이 아닙니다. 여러 클라이언트가 테이블/행과 동시에 상호 작용하지 못하게하려면 잠금을 사용해야합니다. –

+0

내 라이브러리가 mysql_pconnect()를 사용하는 것을 잊어 버렸다. – Cybrix

답변

1

변수는 사용자 단위가 아닌 연결 단위입니다. 두 개의 독립적 인 스크립트를 사용하면 각각 별도의 변수 공간이있는 별도의 독립 연결이 두 개 있습니다.

병렬 사용을 정말로 처리해야하는 경우 GET_LOCK()을 통해 얻은 서버 측 잠금을 사용하거나 리소스에 단독 잠금을 사용하는 트랜잭션 모드를 사용해야합니다.

+0

잠금 장치를 여러 터미널에서 작동 시키려면 파일 잠금보다 더 나은 솔루션입니다. –

+0

나는 그것을 내일 시도하고 당신에게 피드백을 줄 것이다! – Cybrix

0

약간 psudo 코드 : 파일 (/var/tmp/.trans.lck) 인 경우 체크 볼 수있다 이 때 마무리 잠금 파일을 제거 하지 않을 경우 종료 잠금 파일을 생성 경우

+0

스레드 중 하나가 실패하면 icky가 발생할 수 있습니다. – cwallenpoole

+1

MySQL이 전역 잠금, 테이블 잠금, 행 수준 잠금, 자동 잠금을 구현하는 쿼리, 트랜잭션 잠금 모드 등에 대한 액세스를 제공 할 때 자체 잠금 체계를 구현할 이유가 없습니다. –

1

파일 기반 잠금을 사용하십시오.

스크립트가 시작되면 "sync_db.lock"과 같은 파일을 확인하십시오. 존재하는 경우 스크립트의 다른 인스턴스가 실행 중입니다. 이 시점에서 잠을 자고 다시 시작하거나 단순히 포기하도록 선택할 수 있습니다.

존재하지 않는 경우 파일을 만들고 DB 트랜잭션을 완료하십시오. 트랜잭션이 완료되면 파일을 삭제하십시오.

실패한 스레드와 관련된 문제를 방지하려면 파일에 현재 타임 스탬프를 작성하십시오. 스크립트가 파일을 검사 할 때 내용을 읽고 주어진 시간이 지 났는지 확인합니다. 스크립트가 트랜잭션과 함께 계속되면 타임 스탬프를 덮어 쓰는 것을 잊지 마십시오.

관련 문제