2013-08-01 66 views
0

有一個多線程應用程序執行一些PL/pgsql函數。該函數爲極其重要的資源(表格)生成記錄插入。它還執行時執行一些選擇/更新/等操作。postgresql併發查詢調試

問題是,有時候我們會面臨重複的(2-3)記錄,每個記錄在並行線程中傳遞給函數。它們都作爲函數執行結果插入到表中,而它們不應該。

它發生,因爲這兩個事務並行執行,並不知道相同的記錄正在準備插入並行事務。

該表格非常重要,並且各種LOCK TABLE都非常不受歡迎(LOCK FOR SHARE MODE同時給了一些有用的經驗)。

所以,問題是,是否有任何最佳實踐如何組織PL/pgsql函數與關鍵資源(表)一起使用,由多線程應用程序執行並且不會對此資源產生有害的鎖?

PS。我知道,應用程序中由record.ID引發的某個線程是一種可能的解決方案。但我首先對PL/pgsql解決方案感興趣。

+0

假設您沒有主鍵/唯一鍵或通過「重複」鍵,您的意思是除主鍵/唯一鍵之外的其他屬性是否安全?鎖定或序列化訪問是確保條目唯一性的唯一方式,或者至少是我能想到的。 Postgresql 9.2+中可用的資源是可串行化快照隔離(https://wiki.postgresql.org/wiki/SSI),但可能有點重量級滿足您的需求。 – bma

+0

我們有一個PK約束,但它是一個邏輯重複,而不是一個簡單的字段逐字段匹配。對於我們來說,序列化隔離級別不是一個可接受的解決方案:它會產生序列化訪問拒絕可能不可預測地影響應用程序行爲的並行事務。無論如何感謝您的建議! – xacinay

+0

如果你的主鍵允許重複,它不是主鍵嗎?什麼*精確*你的意思是重複。 –

回答

2

有時你可以使用諮詢鎖 - http://www.postgresql.org/docs/current/static/explicit-locking.html。用這些鎖來鎖定一些數字子集。我用它來成功的平行插入同步。

+0

不幸的是,advisory_lock不能做我希望他做的事情。實際上,預計會找到一個數據庫引擎模塊,這將允許我聲明一些鎖定規則,如'從resource_tbl中選擇do_lock(*),其中id在1到100之間「,這意味着數據庫將不允許插入帶有來自間隔的id的新記錄從1到100.所有現有技術,據我所知,只允許我鎖定一些已經存在的記錄。無論如何,我得出了我需要的結論,感謝關注這個問題! – xacinay