我有一種方案,我認爲我需要對所有活動(讀取和寫入)鎖定表。我正在使用Propel 1.6.x,並打算編寫一個小型額外庫來處理鎖定。用於PHP的數據庫中立表鎖定庫
我的使用情況是有(ID,創作者,版本)主鍵的版本表。列對(id,creator)實際上是另一個表上的PK。插入新行時,MAX(版本)以PHP代碼讀取,然後插入行類以供稍後保存。在max和save之間,有一個競爭條件潛能,其中另一個進程可以獲得相同的最大值,然後當然由於非唯一性,其中一個插入會失敗。
爲了避免對鎖的需要,我寧願使用子查詢的保存,是這樣的:
INSERT INTO
test_model_test_organiser_versionable
(id, creator, version)
VALUES (
3,
1,
(
SELECT COALESCE(MAX(version), 1)
FROM test_model_test_organiser_versionable
WHERE id = 3
AND creator = 1
)
);
但是這不是在行走的支持,如果我去做了通過PDO我不會(afaik)有辦法發現賦予複合PK'版本'部分的價值。現在
,我能有額外的自動遞增列,因爲自動遞增值可以在插入之後讀取查找的行,因此我可以在行走做一個重新選擇。但是我想避免無關的專欄,如果我可以幫助它的話 - 在我看來似乎不夠優雅。
所以......我的感覺是,包裹最大&保存在鎖電話是要走的路。這將不得不鎖定整個表IMO,並防止讀取和寫入(否則隨後的最大呼叫不會等待,因此將導致非唯一性再次失敗)。
我需要這與波輪支持的所有平臺上工作,所以 - 除非有更好的辦法,我應該採取 - 有一個PHP庫,將做到這鎖定對任何PDO數據庫?如果不是,我可以自己做 - 但是如果別人已經完成了對各種dbs的測試驢工作(設置MSSQL服務器? - 不用了,謝謝:)
附錄:我發現,在PostgreSQL裏,一個可以做'INSERT INTO X ... RETURNING my_column' - 這將修復它,但可惜不是DB中性! – halfer
我寫PostgreSQL的,使用「LOCK IN test_model_test_organiser_versionable ROW SHARE EXCLUSIVE MODE」鎖定表一類 - 這似乎解決這個問題(我得弄清楚等同於所有其他數據庫平臺)。然而,仍然歡迎答案。 – halfer