首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SQLiteException:无法在事务内启动事务(代码1)

SQLiteException:无法在事务内启动事务(代码1)
EN

Stack Overflow用户
提问于 2014-08-11 13:56:34
回答 3查看 8.6K关注 0票数 10

我在完成一个SQLite事务时遇到了问题,我对如何处理它完全感到困惑。它看起来完全像2007年的这只虫子

我正在创建我的employee表(它引用另一个表entity),如下所示(为简洁而编辑):

代码语言:javascript
运行
复制
CREATE TABLE employee (_id INTEGER NOT NULL, PRIMARY KEY ( _id ) , 
FOREIGN KEY (_id) REFERENCES entity(_id)  ON DELETE cascade ON UPDATE cascade DEFERRABLE INITIALLY DEFERRED )

然后,我按照如下方式运行一个事务(使用SQLiteDatabase对象,我还报告日志中事务的状态):

代码语言:javascript
运行
复制
>> In transaction: false
beginTransaction();
>> In transaction: true
doSomeWrongINSERT();
setTransactionSuccessful();
endTransaction();
>> In transaction: false
SQLiteConstraintException: foreign key constraint failed (code 19)

好吧,一切正常。现在,如果我尝试启动一个新事务或回滚,两者都会失败:

代码语言:javascript
运行
复制
>> In transaction: false
beginTransaction();
android.database.sqlite.SQLiteException: cannot start a transaction within a transaction (code 1)
代码语言:javascript
运行
复制
>> In transaction: false
endTransaction();
java.lang.IllegalStateException: Cannot perform this operation because there is no current transaction.

请注意,如果FKs是即时的,而不是延迟的话,所有这些都不会发生。

Bug报告:https://issuetracker.google.com/issues/37001653

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-08-11 14:29:30

我找到了一个解决办法:关闭DB并再次打开它。它将正确地更新事务状态。

我仍然以编号74751的形式向安卓报告。

票数 4
EN

Stack Overflow用户

发布于 2014-08-11 14:04:55

这似乎是Android中的一个bug。在SQLiteSession类中,endTransactionUnchecked在执行COMMIT之前清除其事务状态(mTransactionStack),并且不期望数据库的事务可能仍然处于活动状态。(我认为,如果没有延迟约束,这种情况是不可能发生的。)

提交错误报告

票数 6
EN

Stack Overflow用户

发布于 2018-01-11 20:57:58

要总结这些答案(感谢:@CL &@m0skit 0),在endTransaction中出现任何异常时,恢复事务状态是值得的。如果要覆盖您的applyBatch实现的ContentProvider,可以在中心位置完成此操作:

代码语言:javascript
运行
复制
    @NonNull
    @Override
    public ContentProviderResult[] applyBatch(@NonNull ArrayList<ContentProviderOperation> operations) throws OperationApplicationException {

        SQLiteDatabase db = mDbHelper.getWritableDatabase();    // automatically opens db, if closed.
        try {
            db.beginTransaction();
            ContentProviderResult[] results = super.applyBatch(operations);
            db.setTransactionSuccessful();
            return results;
        } finally {
            try{
                db.endTransaction();
            }catch (Throwable e2){
                //Log.e(LOG_TAG,"Failed to close a db transaction. The only way to recover is to close the db.", e2);
                db.close();
                throw e2;
            }
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25245041

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档