【问题标题】:What exactly happens after a sql transaction fails in android?android 中的 sql 事务失败后究竟会发生什么?
【发布时间】:2012-08-11 21:31:38
【问题描述】:

如果您使用事务并且sql操作失败,我知道它会回滚所有更改,但是它会在finally语句之后停止所有代码还是将其余代码继续运行?

下面的代码看起来是正确的还是我应该使用 catch 语句?是否可以出于测试目的模拟错误?

public static boolean updateSuccessful = false;

updateToVersion2();
//Does anything after here still run on error?

if(!updateSuccessful) {
    deleteAndRecreateDatabase();
}


public void updateToDbVersion2() {
    this.myDataBase.beginTransaction();
    try {
        this.myDataBase.execSQL("UPDATE myRecords SET column = 'newValue1' WHERE _id = 1");
        this.myDataBase.execSQL("UPDATE myRecords SET column = 'newValue2' WHERE _id = 2");
        this.myDataBase.setTransactionSuccessful();
        // This is not reached on update error, right?
        updateSuccessful = true;
    } finally {
        this.myDataBase.endTransaction();
    }
}

【问题讨论】:

    标签: android


    【解决方案1】:

    您应该捕捉到异常!为什么你把它遗漏了让代码闻起来很糟糕......

    如果在execSQLsetTransactionSuccessful 之间确实发生了异常并最终落入您结束事务的finally 部分怎么办?

    代码可能是这样的:

    public void updateToDbVersion2() {
        boolean fubar = false;
        this.myDataBase.beginTransaction();
        try {
            this.myDataBase.execSQL("UPDATE myRecords SET column = 'newValue1' WHERE _id = 1");
            this.myDataBase.execSQL("UPDATE myRecords SET column = 'newValue2' WHERE _id = 2");
            this.myDataBase.setTransactionSuccessful();
            // This is not reached on update error, right?
            updateSuccessful = true;
        } catch(Exception ex){
            fubar = true;
            // Do whatever is needed to be done such as logcat FOR debugging ONLY!
        } finally {
            if (!fubar){
                // No exceptions occurred, OK to end transaction
                this.myDataBase.endTransaction();
            }
        }
    }
    

    注意finally 子句的条件检查如何确保防止潜在的混乱并确保数据完整性。

    【讨论】:

    • 这有必要吗?我的理解是 finally 将始终运行,如果在没有 setTransactionSuccessful 的情况下达到 endTransaction,它将回滚事务
    【解决方案2】:

    交易本身作为一个整体。它要么成功要么失败,这意味着您要么在数据库中获取所有数据,要么一无所获(当然在此事务中)。 如果事务在某个时候失败,它应该先进入“catch”部分,然后再进入“finally”。

    正如 user827992 所说,捕捉异常会很有趣。那里可能有一些额外的(也许是有价值的)信息。

    【讨论】:

    • 所以没有什么特别的。它会像任何其他错误一样失败,但如果您使用事务,它不会向数据库提交部分更改。
    • 是的,但仍然推荐使用它们。请注意,为数据库中的每个操作打开一个事务。此过程占用了操作的大部分时间。如果您在同一个事务之外对您的数据库提交 20 次更改,则处理时间将乘以 20。如果您将所有这些更改包含在同一个事务中,则只需几毫秒。
    • 感谢您的信息。我在想它比实际上更复杂。
    【解决方案3】:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 2015-10-23
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    相关资源
    最近更新 更多