我有一個應用程序,在PHP + MYSQL plattform運行,使用Doctrine2框架。我需要在一個http請求期間執行3個db查詢:第一個INSERT,第二個SELECT,第三個UPDATE。 UPDATE依賴於SELECT查詢的結果。併發http請求的概率很高。如果出現這種情況,並且DB查詢混淆了(例如,INS1,INS2,SEL1,SEL2,UPD1,UPD2),則會導致數據不一致。我如何確保INS-SEL-UPD操作的原子性?我是否需要使用某種鎖,或者交易是否足夠?併發學說
併發學說
回答
一個表範圍LOCK
保證在所有情況下工作。但是它們很糟糕,因爲它們會阻止併發,而不是處理它。 但是,如果您的腳本在短時間內持有鎖的密碼,它可能是一個可接受的解決方案。
如果你的表使用InnoDB引擎(用於交易的MyISAM不支持),交易是最有效的解決方案,同時也是最複雜的。
的非常具體的需要(在同一個表,先INSERT,第二選擇,第三次更新dependending在SELECT查詢的結果):
- 開始交易
- 插入您的記錄。其他交易將不會看到這些新行,直到自己的事務被提交(除非你使用的是非標準isolation level)
- 與SELECT...LOCK IN SHARE MODE選擇您的結果。您現在對這些行具有READ鎖定,其他人可以更改這些行。 (*)
- 計算您需要計算的任何內容,以確定是否需要更新某些內容。
- 如果需要更新行。
- 提交
- 隨時期待錯誤。如果檢測到死鎖,MySQL可能會決定ROLLBACK您的事務以避免死鎖。如果另一個事務正在更新您嘗試讀取的行,您的事務可能會被鎖定一段時間,甚至超時。
,如果你繼續這樣,您的事務的原子有保證。
一般(*),行不由該SELECT可能仍然在併發事務被插入,即,不存在未在整個交易過程中保證除非proper precautions採取返回
如果您進行交易,問題太大而無法在一般情況下解決。我最好的建議是:閱讀大量關於併發性的知識,瞭解MySQL鎖定/事務如何工作。你可能想詳細描述你的程序的邏輯(你插入了什麼,在哪種情況下你會更新哪一行)。 – RandomSeed
@副:很多編輯。首先,我誤解了你最初的問題。我沒有看到你的問題其實很具體。 – RandomSeed
@YaK的答案實際上是一個很好的答案。你應該知道如何處理一般的鎖。
尋址Doctrine2具體而言,你的代碼應該是這樣的:
$em->getConnection()->beginTransaction();
try {
$toUpdate = $em->find('Entity\WhichWillBeUpdated', $id, \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE);
// this will append FOR UPDATE http://docs.doctrine-project.org/en/2.0.x/reference/transactions-and-concurrency.html
$em->persist($anInsertedOne);
// you can flush here as well, to obtain the ID after insert if needed
$toUpdate->changeValue('new value');
$em->persist($toUpdate);
$em->flush();
$em->getConnection()->commit();
} catch (\Exception $e) {
$em->getConnection()->rollback();
throw $e;
}
的每個後續請求的更新來獲取,會等到其獲取鎖定一個過程本次交易完成。事務成功完成或失敗後,Mysql會自動釋放鎖。缺省情況下,innodb鎖定超時時間爲50秒。所以如果你的進程在50秒內沒有完成事務處理,它將自動回滾並釋放鎖定。您的實體不需要任何其他字段。
- 1. 併發模型mongodb學說symfony
- 2. Symfony2學說合並
- 3. 學說實體發生器
- 4. 學說
- 5. 當學說生成學說/基地/ *。class.php
- 6. Symfony 1.4,學說(學說:: HYDRATE_ARRAY非複數)
- 7. 學說:合併2請求1
- 8. Symfony2的學說
- 9. 使學說
- 10. 學說意義
- 11. 與學說
- 12. 學說+ ZF + phpunit
- 13. 學說2 @joincolumns
- 14. 學說2.0 Bootstrap?
- 15. 學說與MAX()
- 16. 學說querybuilder TO_DAYS
- 17. 學說 - 不在
- 18. 定義學說
- 19. 與學說ORM
- 20. 學說與mamp?
- 21. 學說問題?
- 22. 學說MongoDB ODM
- 23. 學說---搜索
- 24. 學說queryBuilder setParamater
- 25. 學說 - 爲NOW()
- 26. 學說濾波
- 27. 與學說1.2
- 28. 學說 - ManyToOne與
- 29. 理解學說
- 30. PostgreSQL + Rails併發性說明
您打算從一張表或一張表讀取數據嗎? – RandomSeed
只寫入一張表 – puty