저는 여러 번 작업을 처리하는 php 프로그램을 만들고 있습니다. 여러 작업자 프로세스가 자율적으로 작업 테이블을 처리합니다. 각 프로세스는 자신의 mysql 연결을 열어서 (이것은 php의 포크 아키텍처로 인해 필요합니다) 자체 작업 (두 작업자가 동일한 작업을 수행하지 않아야 함)에서 작업해야합니다. 이를 위해 작업자는 작업을 시작하기 전에 작업을 "수행"합니다. 이것은 다음과 같이 이루어진다 :동일한 행을 업데이트하는 여러 프로세스가 mysql에서 교착 상태가 발생합니까?
- 노동자는 모두 "대기"작업이 이러한 작업이 반복되는
- 조회하는
- 트랜잭션이 시작되는 작업을 요청합니다. 그런 다음 스크립트는 상태를 업데이트하여 각 작업을 "수행"하려고합니다. 그 동안 업데이트가 완료되지 않았는지 확인하기 위해 업데이트의 상태는
where status = 'pending'
입니다. - 작업이 성공적으로 "수행"되면 즉시 반복이 중지되고 트랜잭션이 커밋됩니다.
mysql 셸에서이 시나리오를 테스트 한 결과, 2 개의 터미널 창에서 데이터베이스에 처음 두 번 연결되었습니다. 둘 다에서 거래를 시작했습니다. 그런 다음 작업을 첫 번째 창에서 "촬영"하도록 업데이트했습니다. 두 번째 창에서 동일한 작업을 업데이트하려고 시도했습니다. 두 번째 창은 첫 번째 창에서 트랜잭션을 커밋하고 정중하게 실패 할 때까지 기다렸습니다 (0 행이 영향을 받음).
이제 PHP로 (PDO)와 함께 즉시 두 번째 프로세스가 작업을하려고, 나는이 DB에 교착 얻을 :
PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction' in ...
난 단지 포장하는 경우는 잘 모르겠어요를 실제 은 트랜잭션을 수행하여으로 작업을 업데이트합니다. 그러나 내 opinon에서, 내가 프로그램에서 그것을하고있는 방식은 쉘에서 수행 한 동일한 별자리이므로 작동해야합니다.
내가 누락 된 부분을 누군가가 도와 줄 수 있습니까?
작업 표의 유형은 'MyISAM'또는 'InnoDB'입니까? 귀하의 경우에는 'InnoDB'가 설정되어야합니다 –
교착 상태는 무서워 할 것이 아니라 정상입니다. 이러한 유형의 문제를 처리하는 일반적인 방법은 트랜잭션을 다시 시작하는 것입니다. 교착 상태로 인해 실패한 횟수를 추적하고 간단하게 시도를 중지 할 수 있습니다. 작업이 완료되지 않고 다른 작업자가 결국 작업을 포착합니다. –
@ N.B .: 기본적으로 mysql이 "트랜잭션을 시작한 이후로 다른 프로세스가이 행을 이미 업데이트했습니다."라고 말하는 것입니다. 트랜잭션을 어떻게 다시 시작합니까? – Chris