在我的数据库处理程序类(扩展SQLiteOpenHelper)中,我有onCreate()
方法:
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_TASKS);
db.execSQL(CREATE_TABLE_CONTACTS);
}
有时(非常罕见,但仍然)这会导致崩溃,因为显然第一个表已经存在。显然我可以(并且确实)在语句中添加IF NOT EXISTS
来解决这个问题,但我想知道的是,如果表已经存在,onCreate()
将会运行的情况是什么。这通常不会发生,所以我可能搞砸了,但我无法弄明白。
答案 0 :(得分:3)
我想知道如果表已经存在,
onCreate()
将会运行的情况是什么
竞争条件:多个线程尝试通过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同步原语来防止其他线程同时尝试创建数据库。
Singleton同步。确保只有一个数据库助手。
仅在单个线程中访问数据库。