2015-01-09 3 views
1

어떻게 디렉토리에있는 모든 파일에 대해 다음과 같은 작업을 수행, 분마다 실행되도록 예약 된 스크립트의 인스턴스간에 "경쟁 조건"을 처리 할 :펄 SQL 및 파일 생성 경쟁 조건

  1. 연결 SQL 데이터베이스 및 파일의 정보
  2. 이 파일 이름으로 새 레코드를 SQL로 사용할 수있는 다음 파일 이름
  3. 삽입 여러 파일 (여러 폴더)를 생성 테이블에 마지막 요소 (파일 이름)을 확인하고 작성

프로세스가 1 분마다 실행되기 때문에 2 개의 인스턴스가 겹쳐져 동일한 파일에서 작동 할 수 있습니다. 내가 파일 잠금에 의해 것을 방지 할 수 있습니다 이미 열려있는 파일을 건너 뛰는, 그러나 문제와 지속 :이 파일 이름로

  • 만들기 파일을 (이 개 프로세스가 동일한 파일 이름을 사용하려면) 데이터베이스에 사용 가능한 다음 파일 이름을 확인

    프로세스 A는 inputA.jpg를 취하고 파일 이름 image_01로 다음을 사용할 수 있음을 찾습니다.

    프로세스 B는 inputB.jpg를 사용하고 다음 파일 이름이 image_01 인 것을 찾습니다.

    그래서 혼란이 시작

    ...

    불행하게도, 나는 다음 파일 이름이 처리되고 있음을 보여주기 위해 SQL 테이블의 모든 자리 표시 자 기록을 삽입 할 수 없습니다. 루프

    의사 코드 :

    foreach ($file) 
    { 
        $name = findFileNameInSql($file) 
        $path1 = createFile($name, $settings1); 
        $path2 = createFile($name, $settings2); 
        $path3 = createFile($name, $settings3); 
        addToSql($file, $name, $path1, $path2, $path3) 
    } 
    

    실제 코드는 파일 수정 2 개 SQL 트랜잭션 테이블에 삽입 포함 약간 더 복잡하다. createFile() 오류가 발생하면 응용 프로그램은 이전에 작성한 모든 파일을 롤백합니다. 앱의 한 인스턴스가 "abc"파일을 만들고 두 번째 인스턴스에 "abc"파일이 이미 존재한다는 오류가있을 때 분명히 문제가됩니다.

    편집 :

    물론, 제한 스크립트는 해결책이 될 수있는 단 하나의 인스턴스를 가지고,하지만 난 병렬로 실행할 수있는 방법을 찾으려했다. 그것을 할 수있는 방법이 없다면, 이것을 중복으로 닫을 수 있습니다.

  • +0

    http://stackoverflow.com/a/27434074/223226 –

    +0

    @ Сухой27 실제로는 매우 쉬운 해결책입니다. 첫 번째 인스턴스가 60 초보다 오래 걸리면 두 번째 인스턴스가 시작되지 못하도록하는 것이 목표 였지만 충분할 수도 있습니다. 감사. – yosh

    +2

    잠금 파일을 항상'몰려 '할 수 있고 mtimes를 비교할 수 있습니다. – Sobrique

    답변

    0

    데이터베이스에서 동일한 파일 이름을 두 번 반환 할 수 없도록 데이터베이스의 기본 데이터베이스에서 사용 가능한 다음 파일 이름을 반환하는 코드를 만들어야합니다. 이것은 실제로 Perl 문제가 아닌 데이터베이스 문제입니다.

    사용중인 데이터베이스는 밝히지 않았지만 몇 가지 방법이 있습니다. MySQL에서 그것을하는 순진하고 잔인한 방법은 Perl 스크립트가 파일 이름을 가진 테이블에 LOCK TABLE 테이블 WRITE를 수행하는 반면 새로운 파일을 계산하고 그 작업을 수행하는 것입니다. 테이블이 새 파일 이름으로 업데이트되면 잠금을 해제 할 수 있습니다. 테이블 잠금은 트랜잭션과 함께 훌륭하게 작동하지 않습니다.

    또는 데이터베이스 자체 내에서 적절한 잠금을 사용하여 저장 프로 시저를 구현하여 새로운 파일 이름을 반환하는 것과 같이 좀 더 우아하게 처리 할 수 ​​있습니다.

    또는 AUTOINCREMENT 열을 사용하면 테이블에 무언가를 추가 할 때마다 새 번호와 새 파일 이름을 얻을 수 있습니다.

    이것은 모두 매우 복잡 할 수 있습니다. 동시에 여러 개의 트랜잭션이있는 경우 데이터베이스에서이를 어떻게 처리하는지는 일반적으로 구성 가능한 작업이므로 어떤 일이 발생하는지 말할 수는 없습니다.

    코드가 주로 디스크의 데이터를 재구성하는 것처럼 들리면 동시에 여러 작업을 실행하는 데 많은 이점이 없습니다. 이 코드는 아마도 I/O 바인딩 일 것입니다. 어떤 경우에는 한 번에 하나의 복사본 만 실행하도록 다른 사람들이 제안한 코드 변경을 만드는 것이 훨씬 간단합니다.