2011-11-04 39 views
0

我有一種方案,我認爲我需要對所有活動(讀取和寫入)鎖定表。我正在使用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服務器? - 不用了,謝謝:)

+0

附錄:我發現,在PostgreSQL裏,一個可以做'INSERT INTO X ... RETURNING my_column' - 這將修復它,但可惜不是DB中性! – halfer

+0

我寫PostgreSQL的,使用「LOCK IN test_model_test_organiser_versionable ROW SHARE EXCLUSIVE MODE」鎖定表一類 - 這似乎解決這個問題(我得弄清楚等同於所有其他數據庫平臺)。然而,仍然歡迎答案。 – halfer

回答

1

我完全鎖定了表而MAX()和INSERT/UPDATE完成。我找到了這些工作:

  • MySQL的:LOCK TABLES my_table WRITE
  • 的PostgreSQL:LOCK TABLE my_table IN SHARE ROW EXCLUSIVE MODE

我打算查找和測試針對Oracle,MSSQL和SQLite在適當的時候是相同的 - 但前兩個是可能是F/OSS項目最受歡迎的項目。

+0

哦,是的,如果任何人都可以提供我的任何失蹤平臺的等價物,他們可以打勾! – halfer