2009-08-02 9 views
18

Im bawi się psycopg2, a podczas gdy istnieje .commit() i .rollback() nie ma .begin() lub podobne, aby rozpocząć transakcję, lub tak się wydaje? będę oczekiwać, aby być w stanie zrobićJak wykonać transakcje bazy danych za pomocą aplikacji psycopg2/python db api?

db.begin() # possible even set the isolation level here 
curs = db.cursor() 
cursor.execute('select etc... for update') 
... 
cursor.execute('update ... etc.') 
db.commit(); 

Tak, jak pracować z psycopg2 transakcje? Jak ustawić/zmienić poziom izolacji?

Odpowiedz

23

Użyj db.set_isolation_level(n), zakładając, że db jest twoim obiektem połączenia. Jak Federico napisał here, znaczenie n jest:

0 -> autocommit 
1 -> read committed 
2 -> serialized (but not officially supported by pg) 
3 -> serialized 

jako udokumentowane here, psycopg2.extensions daje symboliczne stałe do tego celu:

Setting transaction isolation levels 
==================================== 

psycopg2 connection objects hold informations about the PostgreSQL `transaction 
isolation level`_. The current transaction level can be read from the 
`.isolation_level` attribute. The default isolation level is ``READ 
COMMITTED``. A different isolation level con be set through the 
`.set_isolation_level()` method. The level can be set to one of the following 
constants, defined in `psycopg2.extensions`: 

`ISOLATION_LEVEL_AUTOCOMMIT` 
    No transaction is started when command are issued and no 
    `.commit()`/`.rollback()` is required. Some PostgreSQL command such as 
    ``CREATE DATABASE`` can't run into a transaction: to run such command use 
    `.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)`. 

`ISOLATION_LEVEL_READ_COMMITTED` 
    This is the default value. A new transaction is started at the first 
    `.execute()` command on a cursor and at each new `.execute()` after a 
    `.commit()` or a `.rollback()`. The transaction runs in the PostgreSQL 
    ``READ COMMITTED`` isolation level. 

`ISOLATION_LEVEL_SERIALIZABLE` 
    Transactions are run at a ``SERIALIZABLE`` isolation level. 


.. _transaction isolation level: 
    http://www.postgresql.org/docs/8.1/static/transaction-iso.html 
+0

Nice. Czy domyślnie jest to automatyczne zatwierdzanie? Podczas ustawiania n = 1,2 lub 3, co rozpoczyna transakcję? Tworzenie nowego kursora lub każdej operacji na bazie danych od ostatniego zatwierdzenia/wycofania? – Leeeroy

+0

Autocommit jest domyślny w większości DBMS. –

+1

Alex dodał więcej rzeczy po tym, jak zapytałem. I mówi się, że READ_COMMITED jest domyślnie dla psycopg2 – Leeeroy

5

wolę wyraźnie zobaczyć, gdzie moje transakcje są:

  • kursor.execute ("BEGIN")
  • kursor .execute ("COMMIT")
+2

Czy to z autocommit włączone lub wyłączone? Czy pomieszanie Psycopg2 lub innych modułów baz danych? Zarządzanie transakcjami ODBC używa podobnego podejścia do interfejsu API Pythona DB i widziałem wyraźne ostrzeżenia * nie *, aby używać poleceń zarządzania transakcjami SQL, które podważają interfejs ODBC (np. Http://msdn.microsoft.com/en-us/ library/ms131281.aspx). –

+1

Nie rób tego. Będziesz walczył z funkcją autocommit, nie ma gwarancji, że wynik będzie ładny. –

+2

Jest z autocommit OFF. – peufeu

12

BEGIN z pythonowym standardowym interfejsem API DB jest zawsze niejawny. Podczas rozpoczynania pracy z bazą danych sterownik wydaje numer BEGIN, a po każdym lub ROLLBACK zostaje wydany inny BEGIN. Python DB API zgodny ze specyfikacją powinien zawsze działać w ten sposób (nie tylko postgresql).

Możesz zmienić to ustawienie, aby poziom izolacji był automatycznie anulowany o db.set_isolation_level(n), jak wskazał Alex Martelli.

Teas powiedział, że start jest niejawny, ale nie jest wykonywany, dopóki nie zostanie wykonany SQL, więc jeśli nie wykonasz żadnego SQL, sesja nie znajduje się w transakcji.

+2

Czy to prawda? Wierzę, że po wywołaniu funkcji commit() lub rollback() istnieje _nie_ wyślij kolejne BEGIN natychmiast - jest ono wysyłane niejawnie przy następnym uruchomieniu(). Po zatwierdzeniu()/przywróceniu() połączenie jest w stanie "bezczynności" zamiast "bezczynności w transakcji". – Tebas

+0

Po zatwierdzeniu()/wycofaniu() połączenie jest w stanie "bezczynności". Python DB API wyśle ​​kolejne BEGIN dopiero po innym wykonaniu(), więc nie utworzysz zakleszczenia, jeśli twój program nigdy się nie skończy. Podsumowując po wywołaniu execute() powinieneś commit() lub rollback(), jeśli nie, program będzie "bezczynny w transakcji". – praveenak

Powiązane problemy