如何使用psycopg2/python db api执行数据库事务?

如何使用psycopg2/python db api执行数据库事务?,python,database,postgresql,Python,Database,Postgresql,我在摆弄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,虽然有一个.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一起工作?
如何设置/更改隔离级别?

使用
db。设置隔离级别(n)
,假设
db
是您的连接对象。正如费德里科所写,
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

我更愿意明确地看到我的事务在哪里:

  • cursor.execute(“开始”)
  • cursor.execute(“COMMIT”)

python标准DB API的
开头始终是隐式的。当您开始使用数据库时,驱动程序会发出一个
BEGIN
,并在发出任何
COMMIT
ROLLBACK
后发出另一个
BEGIN
。符合规范的python DB API应该始终以这种方式工作(不仅仅是postgresql)

您可以使用
db将此设置隔离级别更改为自动提交。如Alex Martelli所述,设置隔离级别(n)


正如Tebas所说,begin是隐式的,但在执行SQL之前不会执行,因此如果不执行任何SQL,则会话不在事务中。

Nice。它是否默认为自动提交?当设置n=1、2或3时,什么会启动事务?创建一个新的游标,或者仅仅是自上次提交/回滚以来数据库上的每一个操作?自动提交是大多数DBMS的默认设置。Alex在我询问后添加了更多内容。它说READ_committed是psycopg2的默认值启动事务的是前一个事务的提交或回滚。这是真的吗?我相信在调用commit()或rollback()之后,不会立即发送另一个BEGIN,而是使用next execute()隐式发送。在commit()/rollback()之后,连接处于“idle”状态,而不是“idle in transaction”。在commit()/rollback()之后,连接处于“idle”状态。Python DB API将仅在另一个execute()之后发送另一个BEGIN(),这样,如果程序从未结束,就不会造成死锁。总结一下,一旦调用execute(),您应该提交()或回滚(),否则您的程序将“在事务中处于空闲状态”。这是启用自动提交还是禁用自动提交?它会混淆Psycopg2或其他数据库模块吗?ODBC的事务管理使用了与python DB API类似的方法,我看到过明确的警告,不要使用破坏ODBC接口(例如)的SQL事务管理命令。请不要这样做。你会反对自动提交功能,不能保证结果会很好。它是在自动提交关闭的情况下实现的。自动提交功能也让我感到害怕,所以我想我们是否应该关闭它,然后这样做。如果可以,我很乐意。使用autocommit的原因是,如果您使用pgbouncer这样的外部池,连接将保存到提交,这意味着如果您没有正确管理web服务器上的事务(并实际完全关闭游标),您将有剩余的“事务中空闲”连接。启用“自动提交”后,游标不会自动占用服务器资源,但通过将tcp套接字设置到池中,您仍然可以节省时间。