如何在Java中同时使用SQLite?哪个包装器是最好的选择?

3
首先,我知道SQLite可能不是高并发需求的最合适的DBMS,但目前至少对于我来说,使用客户端/服务器DBMS不是一个选项。
我正在开发的应用程序可能会从不同的线程生成大量的查询和更新。它们不会是非常繁重或复杂的更新,可能大多数是小型且快速的,但是由于它们依赖于从网络上的客户端获得的信息,因此具有极其不可预测性的并发性。据我所知,SQLite目前能够支持许多并发读取,但每次只能更新一个。当它进行写入时,需要获取排他锁,并在写入时如果其他内容正在被写入,则返回异常。
为了解决这个问题,我想应该对更新操作进行队列化(从而使其串行化),并同时从数据库中读取。这对我来说应该足够了。但是我一无所知,我真的不知道该怎么做,因为我一直在使用Zentus JDBC驱动程序,而它似乎不足以满足我现在尝试做的事情。
这就是我的问题,您认为我应该如何做?哪种包装器是实现这一点的适当选择?
提前致谢!
关于SQLite并发性,在他们的网页上说:
“(…)只要连接没有持有任何fcntl()锁,就可以安全地将连接句柄移动到线程之间。如果没有挂起事务并且所有语句都已完成,则可以安全地假定不持有任何锁。”
还有:
“多个进程可以同时打开相同的数据库。多个进程可以同时执行SELECT。但是在任何时刻只能有一个进程对数据库进行更改。”
当SQLite尝试访问被其他进程锁定的文件时,默认行为是返回SQLITE_BUSY。
希望这可以帮助:)

SQLite已经是线程安全的。你遇到了什么问题?你所说的“似乎不足以满足我所要做的事情”是什么意思? - rlibby
是的,连接是线程安全的,但这并不意味着它们可以支持并发写操作,这只意味着您可以在所有想要的线程之间共享连接,如果我没有误解的话...据我所知,如果您尝试在执行另一个任务时进行更新,它将导致“数据库已锁定”异常。 - Eneko
我之前只知道SQLite作为嵌入式数据库,但是我最近在研究时发现还有其他支持嵌入式模式的Java DBMS,例如HSQLDB和H2,它们支持更高的并发性。你了解这些吗?它们是一个好的选择吗? - Eneko
2个回答

2

这取决于你对数据库设计采取的方法,但基本上可以归结为按照Femi建议的方式进行操作,将每个调用都汇聚到一个单一的、同步(或其他锁定)的方法中。

public class DatabaseUpdater
{
    private static final Lock lock = new ReentrantLock();

    public static void doUpdate(DatabaseObject db) throws SQLException
    {
        lock.lock();

        try
        {
            db.doWork();
        }
        finally
        {
            lock.unlock();
        }
    }
}

只要每个人都通过上述调用进行更新,那么它将同步每个调用。

1

你想要的是不是一个 synchronized() 函数?我的意思是,你的多个线程会在等待数据库访问时被阻塞,但只要你足够小心,这应该可以满足你的需求。


这使得对数据库的调用同步进行,但这是否确保所有操作按顺序执行?我不是很确定... SQLite会阻塞直到操作完成吗?即使只使用一个连接,我也不是很确定... - Eneko
它将确保一次只有一个操作被触发(在我看来这看起来相当顺序):它并不涉及操作触发的顺序。如果您需要顺序,我建议创建类似于Vector的东西,并将SQL UPDATE/INSERT/DELETE语句存储其中,然后创建一个线程来读取它们并逐个运行。这会让您接近有序执行,但即使如此,仍无法保证时间顺序。 - Femi
不,这与顺序无关。我的意思是,即使操作不是并发触发的,也并不意味着它们在内部不会同时运行... - Eneko
啊,我非常确定一旦SQLite数据库上的事务完成,它就完成了。 - Femi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接