我正在开发一个必须使用多线程的应用程序。我在整个应用程序中都有一个SQLiteOpenHelper类的实例,其中我有打开和关闭数据库的方法以及一些插入和获取数据的方法。
现在我的问题是,我在第一个线程中打开数据库并同时启动事务,第二个线程也获取打开的数据库对象并启动事务。
第一个线程完成其进程并关闭另一侧的数据库,我的第二个线程正在工作,第二个线程得到数据库已关闭。
这是一些合乎逻辑的问题,请有人帮我解决这个问题,我如何以正确的方式处理关闭数据库。
提前致谢
我正在开发一个必须使用多线程的应用程序。我在整个应用程序中都有一个SQLiteOpenHelper类的实例,其中我有打开和关闭数据库的方法以及一些插入和获取数据的方法。
现在我的问题是,我在第一个线程中打开数据库并同时启动事务,第二个线程也获取打开的数据库对象并启动事务。
第一个线程完成其进程并关闭另一侧的数据库,我的第二个线程正在工作,第二个线程得到数据库已关闭。
这是一些合乎逻辑的问题,请有人帮我解决这个问题,我如何以正确的方式处理关闭数据库。
提前致谢
我在整个应用程序中都有一个 SQLiteOpenHelper 类的实例,其中我有打开和关闭数据库的方法以及一些插入和获取数据的方法。
您应该仅在完全完成数据库后关闭数据库,例如当创建这些线程的活动或服务被销毁时。
根本不关闭数据库也不是不可能的。如果您实施 a ContentProvider
,您将永远不会关闭您的数据库。虽然这可能会导致 LogCat 中有关泄漏打开的数据库句柄的警告,但 SQLite 的事务性质意味着未能关闭数据库不应导致任何特定问题(例如,未能刷新缓冲区)。
通常我只会保持 SQLLite Android DB 打开并在应用程序结束时将其关闭,但这并不能消除最初的问题。
我发现当数据库没有正确关闭时,它可能会在 Android 上打开问题,所以简单的从不关闭数据库似乎对我不起作用。
我将所有操作包装在事务和异常处理程序块中。
请注意,所有事务都需要在我们关闭数据库时完成,因此 close 方法等待事务完成(我也有事务计数器)。
这是一个示例 try catch 事务块,我将所有数据库操作包装在:
SQLPersistentStore 扩展了 SQLiteOpenHelper getPersistentStore() { DB 关闭时返回 null }..
无效公共操作(..){
SQLPersistentStore persistentStore = null;
try {
persistentStore = getPersistentStore();
persistentStore.beginTransaction();
... do the DB operations
persistentStore.setTransactionSuccessful();
} catch ( IllegalStateException e) {
...
Log.w(...
} catch (Exception e) {
Log.e(TAG, ...
throw new RuntimeException(e);
} finally {
if(persistentStore != null){
persistentStore.endTransaction();
}
}
当数据库关闭并且您尝试对其进行操作时,您会得到 IllegalStateException,并且会被捕获。