Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 数据库锁定异常_Android - Fatal编程技术网

Android 数据库锁定异常

Android 数据库锁定异常,android,Android,我在我的应用程序中创建了一个包含5个表的数据库。正在从不同线程更新我的数据库。当我看到日志时,我可以看到,如果数据库已经打开,则在打开数据库时存在数据库锁定异常 我的一个朋友建议我总是使用内容提供商来避免这个问题。据他说,内容提供商自己管理并发问题 如果我们不想将数据共享给其他应用程序,那么使用content provider是否是一种好的做法?问题是您使用了多个数据库连接到数据库。因此,多个线程试图同时更新您的表,并且所有这些线程与您的数据库具有不同的连接 要在所有线程中避免此问题,您需要使用

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

我的一个朋友建议我总是使用内容提供商来避免这个问题。据他说,内容提供商自己管理并发问题


如果我们不想将数据共享给其他应用程序,那么使用content provider是否是一种好的做法?

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

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

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


关于这个问题的讨论可以在这里找到:

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

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

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


关于这个问题的讨论可以在这里找到:

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

假设你写了以下内容

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()将写操作括起来


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

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

假设你写了以下内容

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()将写操作括起来


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

Hey@Takahiko Kawasaki:我尝试了你的解决方案,但我仍然面临这个问题。不确定会出什么问题。应该在databaseHelper classHey@Takahiko Kawasaki的同一个对象上执行。我尝试了你的解决方案,但我仍然面临这个问题。不确定可能出了什么问题。应在databaseHelper类的同一对象上执行