我在我的应用程序中创建了一个包含 5 个表的数据库。我的数据库正在从不同的线程更新。当我看到日志时,如果数据库已经打开,我可以看到在打开数据库时存在数据库锁定异常。
我的一位朋友建议我始终使用内容提供程序来避免这个问题。根据他的说法,内容提供商自己管理并发问题?
如果我们不想将数据共享给其他应用程序,那么使用内容提供程序是一种好习惯吗?
我在我的应用程序中创建了一个包含 5 个表的数据库。我的数据库正在从不同的线程更新。当我看到日志时,如果数据库已经打开,我可以看到在打开数据库时存在数据库锁定异常。
我的一位朋友建议我始终使用内容提供程序来避免这个问题。根据他的说法,内容提供商自己管理并发问题?
如果我们不想将数据共享给其他应用程序,那么使用内容提供程序是一种好习惯吗?
我认为在大多数情况下使用读写锁就足够了。
假设您编写了以下内容,
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class MyDatabase extends SQLiteOpenHelper
{
private static final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
private static void beginReadLock()
{
rwLock.readLock().lock();
}
private static void endReadLock()
{
rwLock.readLock().unlock();
}
private static void beginWriteLock()
{
rwLock.writeLock().lock();
}
private static void endWriteLock()
{
rwLock.writeLock().unlock();
}
那么你可以像下面这样完成你的任务。
public static void doSomething()
{
SQLiteDatabase sldb = null;
try
{
beginReadLock();
MyDatabase mydb = new MyDatabase();
sldb = mldb.getReadableDatabase();
......
}
catch (Exception e)
{
......
}
finally
{
if (sldb != null)
{
try
{
sldb.close();
}
catch (Exception e) {}
}
endReadLock();
}
}
用beginReadLock()和endReadLock()附上读取操作。同样,用beginWriteLock()和endWriteLock()附上写操作。
几个月前,通过上述解决方案,我可以解决我自己的数据库锁定问题,即多个线程同时尝试读/写打开数据库。
问题是您使用多个数据库连接到您的数据库。因此,多个线程尝试同时更新您的表,并且所有这些线程都与您的数据库有不同的连接。
为避免在所有线程中出现此问题,您需要使用与数据库的相同连接,即所有线程应使用与数据库的相同连接(由 SQLiteDabase 对象表示)。
此外,由于 sqlite 文件上有一个文件块,因此使用多个线程不会提高数据库升级的性能(最好只使用一个线程来处理数据库)。如果你想使用多个线程,你应该使用同一个数据库连接,在这种情况下,Android 将管理锁。
您可以在此处找到有关此问题的讨论:http: //touchlabblog.tumblr.com/post/24474398246/android-sqlite-locking和此处:Android 上 SQLite 的最佳实践是什么?