在我的数据库处理程序类(扩展 SQLiteOpenHelper)中,我有 onCreate()
方法:
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_TASKS);
db.execSQL(CREATE_TABLE_CONTACTS);
}
有时(非常罕见,但仍然)这会导致崩溃,因为显然第一个表已经存在。显然我可以(并且确实)将 IF NOT EXISTS
添加到语句中来解决此问题,但我想知道的是运行 onCreate()
的情况如果表已经存在。这通常是不应该发生的,所以我可能搞砸了一些事情,但我不知道是什么。
最佳答案
I want to know is what are the circumstances where
onCreate()
would be run if the table already exists
竞争条件:多个线程尝试通过 getReadableDatabase()
或 getWritableDatabase()
获取数据库的控制权。
特别是如果线程在 code 中的 getVersion()
和 setVersion()
之间交错。 :
242 final int version = db.getVersion();
243 if (version != mNewVersion) {
...
251 if (version == 0) {
252 onCreate(db);
253 } else {
254 if (version > mNewVersion) {
255 onDowngrade(db, version, mNewVersion);
256 } else {
257 onUpgrade(db, version, mNewVersion);
258 }
259 }
260 db.setVersion(mNewVersion);
涉及大量处理和一些磁盘 I/O,因此两个线程在这场竞争中结束并不困难。
可能的解决方案:
同步:使用 Java 同步原语来防止其他线程同时尝试创建数据库。
具有同步功能的单例。确保只有一个数据库助手。
仅在单个线程中访问数据库。
关于android - SQLiteOpenHelper onCreate 运行两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26127147/