2009-08-02 17 views
18

Im không quan trọng với psycopg2, và trong khi có một .commit() và .rollback() không có .begin() hoặc tương tự để bắt đầu một giao dịch, hoặc có vẻ như vậy? Tôi mong đợi để có thể làmLàm cách nào để thực hiện các giao dịch cơ sở dữ liệu với api psycopg2/python db?

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

Vậy, các giao dịch hoạt động với psycopg2 như thế nào? Làm cách nào để đặt/thay đổi mức cách ly?

Trả lời

23

Sử dụng db.set_isolation_level(n), giả sử db là đối tượng kết nối của bạn. Như Federico viết here, ý nghĩa của n là:

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

như tài liệu here, psycopg2.extensions mang đến cho bạn hằng mang tính biểu tượng với mục đích:

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

Tốt. Liệu nó mặc định để autocommit? Khi thiết lập n = 1,2 hoặc 3 cái gì bắt đầu một giao dịch? Tạo một con trỏ mới, hoặc chỉ mọi hoạt động trên db từ lần commit/rollback cuối cùng? – Leeeroy

+0

Autocommit là mặc định trong hầu hết các DBMS. –

+1

Alex đã thêm nhiều nội dung sau khi tôi hỏi. Và nó nói READ_COMMITED là mặc định cho psycopg2 – Leeeroy

5

tôi thích nhìn thấy một cách rõ ràng nơi giao dịch của tôi là:

  • cursor.execute ("BEGIN")
  • con trỏ .execute ("COMMIT")
+2

Đó có phải là tự động bật hoặc tắt không? Nó sẽ gây nhầm lẫn Psycopg2, hoặc các mô-đun cơ sở dữ liệu khác? Quản lý giao dịch của ODBC sử dụng cách tiếp cận tương tự với API DB python và tôi đã thấy các cảnh báo rõ ràng * không * để sử dụng các lệnh quản lý giao dịch SQL làm hỏng giao diện ODBC (ví dụ: http://msdn.microsoft.com/en-us/ library/ms131281.aspx). –

+1

Xin đừng làm vậy. Bạn sẽ chiến đấu chống lại chức năng tự động, không có gì đảm bảo kết quả sẽ đẹp. –

+2

Nó có tính năng TẮT tự động. – peufeu

12

BEGIN với API DB chuẩn python luôn ẩn. Khi bạn bắt đầu làm việc với cơ sở dữ liệu, trình điều khiển sẽ phát hành một số BEGIN và sau bất kỳ COMMIT hoặc ROLLBACK một số khác là BEGIN. Một DBBC python tuân thủ các đặc điểm kỹ thuật nên luôn luôn làm việc theo cách này (không chỉ postgresql).

Bạn có thể thay đổi cài đặt này mức cô lập thành tự động với db.set_isolation_level(n) như được chỉ bởi Alex Martelli.

Như Tebas nói bắt đầu là ngầm định nhưng không được thực hiện cho đến khi SQL được thực hiện, vì vậy nếu bạn không thực thi bất kỳ SQL nào, phiên đó không có trong giao dịch.

+2

Điều đó có đúng không? Tôi tin rằng sau khi một cuộc gọi của cam kết() hoặc rollback() có _not_ gửi một BEGIN ngay lập tức - nó được gửi ngầm với thực thi tiếp theo(). Sau một cam kết()/rollback() kết nối đang ở trạng thái 'nhàn rỗi' thay vì 'nhàn rỗi trong giao dịch'. – Tebas

+0

Sau một cam kết()/rollback() kết nối đang ở trạng thái 'nhàn rỗi'. API DB của Python sẽ chỉ gửi một BEGIN khác sau khi thực hiện lệnh khác() để bạn không tạo ra bế tắc nếu chương trình của bạn không bao giờ kết thúc. Để tóm tắt một khi bạn gọi execute(), bạn nên commit() hoặc rollback() nếu không chương trình của bạn sẽ là "nhàn rỗi trong giao dịch". – praveenak

Các vấn đề liên quan