2010-08-19 137 views
7

我們正在使用SQLAlchemy聲明基礎,並且我有一個方法要隔離事務級別。爲了解釋,有兩個進程同時寫入數據庫,我必須讓他們在事務中執行邏輯。默認事務隔離級別是READ COMMITTED,但我需要能夠使用SERIALIZABLE隔離級別執行一段代碼。如何在SQLAlchemy for PostgreSQL中設置事務隔離級別?

這是如何使用SQLAlchemy完成的?現在,我基本上在我們的模型中有一個方法,它繼承自SQLAlchemy的聲明基礎,本質上需要事務性調用。

from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT 
from psycopg2.extensions import ISOLATION_LEVEL_READ_COMMITTED 
from psycopg2.extensions import ISOLATION_LEVEL_SERIALIZABLE 

class OurClass(SQLAlchemyBaseModel): 

    @classmethod 
    def set_isolation_level(cls, level=ISOLATION_LEVEL_SERIALIZABLE): 
     cls.get_engine().connect().connection.set_isolation_level(level) 

    @classmethod 
    def find_or_create(cls, **kwargs): 
     try: 
      return cls.query().filter_by(**kwargs).one() 
     except NoResultFound: 
      x = cls(**kwargs) 
      x.save() 
      return x 

我這樣做此使用事務隔離級別調用,但它不是做我的期望。隔離級別仍然是從我在postgres日誌中看到的READ COMMITTED。有人可以幫助確定我在做什麼錯嗎?

我使用的SQLAlchemy 0.5.5

class Foo(OurClass): 

    def insert_this(self, kwarg1=value1): 
     # I am trying to set the isolation level to SERIALIZABLE 
     try: 
      self.set_isolation_level() 
      with Session.begin(): 
       self.find_or_create(kwarg1=value1) 
     except Exception: # if any exception is thrown... 
      print "I caught an expection." 
      print sys.exc_info() 
     finally: 
      # Make the isolation level back to READ COMMITTED 
      self.set_isolation_level(ISOLATION_LEVEL_READ_COMMITTED) 

回答

7

從邁克爾·拜爾的SQLAlchemy的維護者:

請使用 「ISOLATION_LEVEL」 參數create_engine() 和使用latest tip of SQLAlchemy 直到0.6.4被釋放,因爲有一個 psycopg2 - 關於隔離級別最近修復的特定錯誤 。

你有下面的方法不 影響是 後來用於查詢相同的連接 - 你會 改用PoolListener,設置所有連接 高達 作爲set_isolation_level創建它們。

+3

似乎'create_engine()'的'isolation_level'參數僅影響主連接管理器,因此您可以在每個連接上獲得該隔離級別。你有沒有想出一個連接池兼容的方式來實現這個每會話/連接的基礎?你原來的問題似乎只是你想要某種方法。 – Russ 2010-12-14 02:58:43

-3

隔離級別被設置在一個事務中,例如

try: 
    Session.begin() 
    Session.execute('set transaction isolation level serializable') 
    self.find_or_create(kwarg1=value1) 
except: 
    ... 

PostgreSQL doc

如果SET交易沒有啓動之前事務執行或BEGIN,它會出現沒有任何效果,因爲該交易將立即結束。

+0

我會明天測試你的答案,並接受它,如果它的工作:)我有一種感覺它會。 – 2010-08-23 02:40:53

+0

你的回答不起作用。根據Michael Bayer的說法,它看起來像事務隔離級別不會影響稍後用於查詢的同一連接。 – 2010-08-24 01:54:09

+0

我相信Michael Bayer的評論是關於你的代碼的,而不是我的。區別在於你在開始事務之前設置了隔離級別。聲稱它不起作用之前,你真的嘗試過這些代碼嗎? – sayap 2010-08-27 12:13:22