我有一个包含一些表的数据库。 我想使用多个线程更新表。 我将在所有线程中使用相同的SQLiteDatabase实例。
请说明这种方法是否正确。 Sqlite数据库线程安全吗? 两个不同的线程可以同时为不同的值集更新同一个表。
答案 0 :(得分:27)
[错误:]不,默认情况下它不是线程安全的。你应该使用与锁相关的SQLiteHelper方法来提供线程安全性。
[编辑]: SQLiteDatabase类提供了一个锁定机制默认情况下(请参阅注释),如果您在多线程上运行,则不必考虑更改任何内容有线程安全。
在本文档中搜索“主题”:http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
阅读更多内容:
答案 1 :(得分:5)
Android使用java锁定机制来保持SQLite数据库访问序列化。因此,如果多个线程有一个数据库实例,它总是以序列化方式调用数据库,当然数据库是线程安全的。
如果我们确认我们正在使用来自单线程的数据库,我们可以选择通过调用setLockingEnable(false)
来设置数据库内部锁定禁用,但此方法从API级别16获得deprecated并且不再使用。如果你在SQLiteDatabase
类中看到这个方法的实现,你会发现那里没有写任何东西,即空方法。
public void setLockingEnabled (boolean lockingEnabled)
此方法现在什么都不做。不要使用。
我们应该注意的一件事是我们应该创建一个helper类的实例(即通过使它成为单例)并将相同的实例共享到多个线程,并且在操作之间不要在数据库上调用close()
,否则您可能会遇到以下异常:
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase
因此,在访问数据库之间不要调用database.close()
,当所有操作完成时,数据库将在内部自行执行关闭操作。
答案 2 :(得分:2)
您可以通过setLockingEnabled控制数据库是否是线程安全的。
通过使用关键部分周围的锁来控制SQLiteDatabase是否成为线程安全的。这非常昂贵,因此如果您知道您的数据库只会被单个线程使用,那么您应该将其设置为false。默认值为true
所以我认为这回答了你的问题。
方法setLockingEnabled在API级别16中折旧
答案 3 :(得分:-2)
如果你做到了..
setLockingEnabled(boolean lockingEnabled) 通过在关键部分周围使用锁来控制SQLiteDatabase是否成为线程安全的。