2011-08-03 16 views
2

我正在使用Python apsw綁定來處理SQLite數據庫。該代碼是這樣的:SQLite(Python apsw)無法回滾,因爲它很忙

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。

回答

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(...) 
3

這是SQLite中本身就是一個問題。它於2012年3月在3.7.11版中得到修復。從changelog

待處理語句不再阻止ROLLBACK。相反,待處理語句在ROLLBACK後的下一次訪問時將返回SQLITE_ABORT。

相關問題