2010-08-19 12 views
7

Korzystamy z deklaratywnej podstawy SQLAlchemy i mam metodę, dla której chcę wyizolować poziom transakcji. Aby to wyjaśnić, istnieją dwa procesy, które jednocześnie zapisują do bazy danych i muszę ich wykonać logicznie w transakcji. Domyślnym poziomem izolacji transakcji jest READ COMMITTED, ale muszę mieć możliwość wykonania fragmentu kodu przy użyciu poziomów izolacyjnych SERIALIZABLE.Jak ustawić poziom izolacji transakcji w SQLAlchemy dla PostgreSQL?

Jak to się dzieje przy użyciu SQLAlchemy? W tej chwili zasadniczo mam metodę w naszym modelu, która dziedziczy po deklaratywnej bazie SQLAlchemy, która zasadniczo musi być wywoływana w sposób transakcyjny.

Robię to, aby wywołać to za pomocą poziomu izolacji transakcji, ale nie robię tego, czego się spodziewam. Poziom izolacji nadal jest READ COMMITTED z tego, co widzę w dziennikach postgres. Czy ktoś może pomóc w identyfikacji tego, co robię?

mi stosując 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) 

Odpowiedz

7

Od Michael Bayer, opiekuna SQLAlchemy:

Proszę użyć "isolation_level" argument create_engine() i obsługi latest tip of SQLAlchemy aż 0.6.4 jest zwolniony, ponieważ nie było psycopg2 -specific bug naprawiony ostatnio w odniesieniu do poziomu izolacji.

Podejście masz poniżej nie wpływa na samo połączenie, które jest później wykorzystywane do wysyłania zapytań - Można by zamiast użyć PoolListener który ustawia się set_isolation_level wszystkich połączeń, ponieważ są one tworzone.

+3

Wygląda na to, że argument 'isolation_level' dla' create_engine() 'wpływa tylko na główny menedżer połączeń, więc dostajesz ten poziom izolacji dla każdego połączenia. Czy udało ci się znaleźć sposób kompatybilny z łączeniem puli, aby osiągnąć ten cel w przeliczeniu na sesję/połączenie? Twoje pierwotne pytanie wyglądało tak, jakbyś chciał tylko tego na pewnej metodzie. – Russ

-3

poziom izolacji jest w trakcie transakcji, na przykład

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

Od PostgreSQL doc:

Jeśli zbioru transakcji jest realizowana bez wcześniejszej rozpocząć transakcji lub rozpocząć, to wydaje się mieć żadnego wpływu, ponieważ transakcja zostanie natychmiast skończyć.

+0

Sprawdzę twoją odpowiedź jutro i zaakceptuję to, jeśli to działa :) Mam wrażenie, że to zrobi. –

+0

Twoja odpowiedź nie działa. Według Michaela Bayera wygląda na to, że poziom izolacji transakcji nie wpływa na to samo połączenie, które jest później używane do odpytywania. –

+0

Wierzę, że komentarz Michaela Bayera dotyczy kodu, a nie mojego. Różnica polega na tym, że twój poziom izolacji jest ustalany przed rozpoczęciem transakcji. Czy naprawdę wypróbowałeś kod przed zgłoszeniem, że nie działa? – sayap

Powiązane problemy