如何使用psycopg2/python数据库API进行数据库事务?

31 投票
3 回答
40614 浏览
提问于 2025-04-15 13:20

我正在玩弄psycopg2这个库,发现它有.commit()和.rollback()这两个方法,但似乎没有.begin()或者类似的东西来开始一个事务?我本来以为可以这样做:

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

那么,psycopg2中的事务是怎么运作的呢?我该如何设置或更改隔离级别呢?

3 个回答

10

我喜欢清楚地看到我的操作在哪里:

  • cursor.execute("BEGIN")
  • cursor.execute("COMMIT")
19

在使用Python的标准数据库接口时,BEGIN这个操作是自动进行的。当你开始和数据库打交道时,驱动程序会自动发出一个BEGIN,然后在你执行任何COMMIT(提交)或ROLLBACK(回滚)操作后,又会发出一个新的BEGIN。符合这个标准的Python数据库接口应该都是这样工作的(不仅仅是PostgreSQL)。

你可以通过db.set_isolation_level(n)来改变这个设置,使其变为自动提交,正如Alex Martelli所提到的那样。

正如Tebas所说,BEGIN是自动的,但在你执行SQL语句之前并不会真正执行,所以如果你没有执行任何SQL,当前会话就不会处于事务状态。

36

使用 db.set_isolation_level(n),假设 db 是你的连接对象。正如Federico在这里所写的,n 的含义是:

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

根据文档这里psycopg2.extensions为你提供了符号常量,用于这个目的:

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

撰写回答