SQLite(Python apsw)无法回滚,因为它很忙

时间:2011-08-03 22:00:53

标签: python sqlite

我正在使用Python apsw绑定使用SQLite数据库。代码如下:

with apsw.Connection(path) as t:
    c = t.cursor()
    c.execute(...)
    ... more code ...
    if c.execute(...).next()[0]:
        raise Exception

我希望with语句将一个保存点和raise语句回滚到该保存点(或者,如果没有任何东西可以提交,则提交事务)。它提交得很好,但是当有raise的东西时,它拒绝回滚:

BusyError: BusyError: cannot rollback savepoint - SQL statements in progress

我不确定先看哪里。据我所知,错误意味着还有另一个阻止访问的连接,但是从代码看起来并不是这样,如果是这样的话,它也不会在提交时失败吗?

SQLite 3.7.7.1,匹配apsw,Python 2.7。

2 个答案:

答案 0 :(得分:3)

好吧,我找到了它:

if c.execute(...).next()[0]:
    raise Exception

问题是,当我得到next()的下一行时,底层游标保持活动状态,准备返回更多行。它必须明确关闭:

if c.execute(...).next()[0]:
    c.close()
    raise Exception

或隐含地,通过读出所有数据:

if list(c.execute(...))[0][0]:
    raise Exception

更新。为方便起见,我写了一个包装apsw.Cursor并提供a context manager的Python类,所以我可以写:

with Cursor(connection) as c:
    c.execute(...)

答案 1 :(得分:3)

这是SQLite本身的一个问题。它在2012年3月修订,版本为3.7.11。来自changelog

  

待处理语句不再阻止ROLLBACK。相反,挂起语句将在ROLLBACK之后的下一次访问时返回SQLITE_ABORT。