Sqlite数据库实例线程是否安全

Man*_*ish 31 sqlite android locking thread-safety

我有一个包含一些表的数据库.我想使用多个线程更新表.我将在所有线程中使用相同的SQLiteDatabase实例.

请建议这种方法是否正确.Sqlite数据库线程安全吗?两个不同的线程可以同时为不同的值集更新同一个表.

Ahm*_*gle 27

[错误:]不,默认情况下它不是线程安全的.您应该使用与锁相关的SQLiteHelper方法来提供线程安全性.

[编辑]: SQLiteDatabase类默认提供锁定机制(请参阅注释),如果您在多线程上运行,则不必考虑更改任何内容以保证线程安全.

在本文档中搜索"thread":http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

阅读更多内容:

  • http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#setLockingEnabled%28boolean%29通过使用关键部分周围的锁来控制SQLiteDatabase是否成为线程安全的.这非常昂贵,因此如果您知道您的数据库只会被单个线程使用,那么您应该将其设置为false.默认值为true ... ...这是否意味着默认情况下它是IS线程安全的? (11认同)
  • “此方法在 API 级别 16 中已弃用。此方法现在什么也不做。请勿使用。” (3认同)

Akh*_*bey 5

Android使用java锁定机制来保持SQLite数据库访问序列化.因此,如果多个线程有一个数据库实例,它总是以序列化方式调用数据库,当然数据库是线程安全的.

如果我们确认我们正在使用来自单线程的数据库,我们可以选择通过调用来设置数据库内部锁定禁用,setLockingEnable(false)但是此方法已从API级别16 弃用并且不再使用.如果你在SQLiteDatabase课堂上看到这个方法的实现,你会发现没有写在那里,即空方法.

public void setLockingEnabled (boolean lockingEnabled)
Run Code Online (Sandbox Code Playgroud)

此方法现在什么都不做.不使用.

我们应该注意的一件事是我们应该创建一个helper类的实例(即通过使它成为单例)并将相同的实例共享到多个线程,并且不在close()操作之间调用数据库,否则您可能会遇到以下异常:

java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase

因此,不要database.close()在访问数据库之间调用,数据库将在所有操作完成后在内部自行执行关闭操作.