저는 간단한 스크립트를 실행하여 무결성 문제를 해결할 수있는 솔루션을 테스트하고 있습니다. 나는 테이블 my_table
왜 업데이트 예제 작업을 선택합니까?
|foo |
|1 |
이 그리고이 두 조각이 있다고 가정 :
// db_slow.php
<?php
$db = new PDO('mysql:host=localhost;dbname=my_playground;charset=utf8', 'root', '');
echo 'starting transaction<br />';
$db->beginTransaction();
$stmt = $db->query('select * from my_table for update');
$rows = $stmt->fetchAll();
echo 'count tables: ', count($rows), '<br />';
if (count($rows) == 1) {
sleep(10);
$db->query('insert into my_table(foo) VALUES(2)');
}
$db->commit();
echo 'done';
// db_fast.php
<?php
$db = new PDO('mysql:host=localhost;dbname=my_plyaground;charset=utf8', 'root', '');
echo 'starting transaction<br />';
$db->beginTransaction();
$stmt = $db->query('select * from my_table for update');
$rows = $stmt->fetchAll();
echo 'count tables: ', count($rows), '<br />';
if (count($rows) == 1) {
$db->query('insert into my_table(foo) VALUES(3)');
}
$db->commit();
echo 'done';
db_slow.php
이 경쟁 조건을 시뮬레이션하기 위해 10 초 지연이 있습니다.
내가 알고 있듯이 select ... for update
은 선택한 모든 행을 잠급니다. db_slow
을 실행하면 db_fast
이 표시되고 이 예상대로 대기하므로 db_fast
도 10 초 지연됩니다.
// db_slow.php
starting transaction
count tables: 1
done
// db_fast.php
starting transaction
count tables: 2
done
그리고
|foo |
|1 |
|2 |
my_table
내가, select ... for update
잠금이 선택하는 모든 행을 알고있는 것처럼 :
그러나, 내가 무엇을하지 않는 것은이 출력된다 트랜잭션. 행 1을 선택하려고,이 잠겨 있음을 참조하십시오
- db_slow : 선택 행 1과는
- db_slow 잠금 : 그것은 단지 1 행 있다고보고
- db_fast 기다려 그래서 내가 기대하는 것입니다
- db_slow을 기다립니다 '2'
- db_fast에 행을 삽입 : 1 행 잠금이 해제되기 때문에 계속
- db_fast : 만이 삽입하므로, 1 개 행을 선택한 '3'
- 끝을로
위에서 설명한 출력과 지연은 단계 1, 2, 3을 확인하는 것 4. 잠금을 확보하려고 후 선택 실행 db_fast
것 같아? 한 행을 선택한 다음 잠 그거나 기다릴 것이라고 생각했습니다.
다소 관련 질문 : select ... lock in share mode
이것을 실행하면
나는
// db_slow.php
starting transaction
count tables: 1
done
// db_fast.php
starting transaction
count tables: 1
done
그리고 my_table
|foo |
|1 |
|3 |
왜 db_slow
행을 '삽입되지 끝낼 2 '1 행만 있다고 생각할 때조차도 테이블 (행을 삽입하는 조건)?
이 코드는 어딘가에 있어야합니다. – sgroves
하나의 연결은 my_playground에 연결되고 다른 연결은 adrian_playground_alpha - typo입니까? – Alden
@sgroves 이런 쓰레기는 이전에 '공유 모드에서 잠금'을 시도했지만 다시 변경하는 것을 잊어 버렸습니다. 그것은 당황 스럽지만, 비슷한 것을 업데이트 용으로 바꿀 때 일어납니다. @Alden 미안하다. 같은 데이터베이스에서 실행 중이며 여러 스크립트가 있고 여기에 붙여 넣은 모든 불일치를 수정하는 것을 잊어 버렸다. – Raekye