gpt4 book ai didi

android - 违反延迟外键约束的事务未结束

转载 作者:行者123 更新时间:2023-12-05 06:20:46 25 4
gpt4 key购买 nike

我有一个包含实体 AB 的 Room 数据库。 B 通过外键引用 A。外键设置为延迟到事务结束:

@ForeignKey(entity = A.class, deferred = true, parentColumns = "_id", childColumns = "A_id")

当我在事务中删除 A 中被 B 中的行引用的行时(例如使用 RoomDatabase.runInTransaction()),事务失败并抛出 SQLiteConstraintException,正如预期的那样。但是,当我尝试在同一个数据库对象上启动另一个事务时,出现以下异常:

android.database.sqlite.SQLiteException: cannot start a transaction within a transaction (code 1 SQLITE_ERROR)

此外,还会向 Logcat 打印以下内容:

E/SQLiteLog: (1) statement aborts at 3: [BEGIN EXCLUSIVE;] cannot start a transaction within a transaction

因此,当抛出 SQLiteConstraintException 时,看起来初始事务并未在底层 SQLite 层中结束。这是有意为之的行为吗?

从这个状态来看,似乎没有办法结束底层交易。调用 RoomDatabase.inTransaction() 会产生 false,并且 RoomDatabase.endTransaction()(标记为已过时)不会结束事务。

我使用的是 Room 版本 2.1.0。

最佳答案

发生这种情况是因为 bug在 SQLiteDatabase 类中:如果您将 FK 设置为 DEFERRABLE INITIALLY DEFERRED 并且它在事务期间失败,在 commit() 之后,数据库 session Controller 将处于不稳定状态,它不允许新事务也不允许关闭前一个事务。

有一个workaround :关闭数据库并再次打开它。这将正确更新交易状态。

我更喜欢在提交事务之前手动检查 FK 约束,并在违反 FK 的情况下抛出 SQLiteConstraintException 异常。可以使用 PRAGMA foreign_key_check

进行检查

关于android - 违反延迟外键约束的事务未结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60271313/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com