2012-07-22 84 views
4

我對數據庫相對比較陌生。我確信這是經驗會回答的問題。用SQLAlchemy處理事務衝突

我在PostgreSQL中使用SQLAlchemy。我有一個系統設置多個進程分佈在多臺計算機上執行各種任務,然後更新數據庫。我在測試中還沒有遇到任何交易衝突,但它們在理論上仍然可能。

從我在Google上能找到的信息來看,我要麼必須獲取數據庫的鎖定,要麼準備重新啓動事務。遺憾的是,有關如何實際上做到這個寶貴的小信息。

我認爲,要重新啓動事務,SQLAlchemy拋出一些異常,我的代碼必須捕獲並執行重試本身。如果我違反唯一性約束,指出我的代碼中存在與事務衝突相對的錯誤,那麼該異常是否會與SQLA不同?我會更好地使用數據庫鎖嗎?

在此先感謝!

- 編輯 -

我剛剛學會了 「ConcurrentModificationError」。名字肯定聽起來像我正在尋找的懷疑。 The documentation表示它是StaleDataError的別名,它的名字聽起來不錯,但其文檔非常不透明。這是我正在尋找的錯誤嗎?

再次,非常感謝!

回答

1

我從來沒有見過這個錯誤,儘管StaleModificationError的詳細信息表明它可能是您關心的事情,但不應該鎖定整個數據庫。您可能會閱讀transaction isolation in Postgres以防止不同流程工作人員在不知不覺中讀取正在另一個事務中更新的行。

如果您將隔離級別設置得更高(讀取提交等),那麼您的SA會話將開始收集它所觸及的各行上的鎖。您決定爲您的設計設置隔離級別有多嚴格。您可以使其足夠嚴格,當讀者嘗試讀取另一個事務已鎖定的行時,您的讀者會拋出異常,然後您可以選擇回滾或使用refresh/expire interface來更新該特定會話。

1

只需在khoxsey的答案中添加一些細節即可。

如果事務隔離級別設置爲「可序列化」,將導致PostgreSQL在併發事務相互干擾時引發錯誤。當有很多併發數據庫連接時,「可串行化」隔離級別會降低性能,但在我的情況下,性能不成問題的可能性不大。

當事務在這個序列化級別相互衝突時,Postgres將其稱爲「序列化錯誤」,它具有「40001」的SQLSTATE error code。目前沒有可用驅動程序訪問SQLAlchemy中的SQLSTATE的方式。但是,使用psycopg2驅動程序時,可以通過exc.orig.pgcode訪問SQLSTATE代碼,其中exc捕獲的異常,但語句除外。

從我可以告訴,異常本身應該是一個OperationalError。