数据库锁定异常

时间:2012-06-26 18:11:19

标签: android

我在我的应用程序中创建了一个包含5个表的数据库。我的数据库正在从不同的线程更新。当我看到日志时,如果数据库已经打开,我可以看到在打开数据库时存在数据库锁定异常。

我的一位朋友建议我始终使用内容提供商来避免此问题。根据他的内容提供商自己管理并发问题?

如果我们不想将数据共享给其他应用程序,那么使用内容提供商是一种好习惯吗?

2 个答案:

答案 0 :(得分:4)

我认为在大多数情况下使用读写锁就足够了。

假设您已编写以下内容,

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()包含写操作。

几个月前,通过上述解决方案,我可以解决自己的数据库锁定问题,其中多个线程试图同时读/写 - 打开数据库。

答案 1 :(得分:1)

问题是您使用多个数据库连接到数据库。因此,多个线程尝试同时更新您的表,并且所有这些线程都与您的数据库具有不同的连接。

要在所有线程中避免此问题,您需要使用与数据库相同的连接,即所有线程都应使用与数据库相同的连接(由SQLiteDabase对象表示)。

此外,因为sqlite文件上有一个文件块,你不会使用多个线程来提高数据库升级的性能(最好只使用一个线程来处理数据库)。如果要使用多个线程,则应使用与数据库相同的连接,在这种情况下,Android将管理锁。

您可以在此处找到有关此问题的讨论:http://touchlabblog.tumblr.com/post/24474398246/android-sqlite-locking和此处:What are the best practices for SQLite on Android?