我有一个使用 sqlite 数据库的 Web 应用程序。我的 sqlite 版本是官方 windows 二进制发行版的最新版本 - 3.7.13。
问题是在数据库负载很重的情况下,sqlite API 函数(例如 sqlite3_step)正在返回 SQLITE_BUSY。
初始化连接时,我传递了以下编译指示:
journal_mode = WAL
page_size = 4096
synchronous = FULL
foreign_keys = on
数据库是单文件数据库。我正在使用它提供的 Mono 2.10.8 和 Mono.Data.Sqlite 程序集来访问数据库。
我正在使用 50 个并行线程对其进行测试,这些线程分别向我的应用程序发送 50 个后续 http 请求。在每次请求时,都会对数据库进行一些读取和写入。每组 IO 操作都在事务内部执行。
一切顺利,直到接近第 400 - 700 个请求。在这个(随机)时刻,API 函数开始永久返回 SQLITE_BUSY(更准确地说 - 直到达到重试限制)。
据我所知,WAL 模式透明地支持并行读写。我猜这可能是因为在执行检查点操作时尝试读取数据库。但即使关闭自动检查点,情况仍然相同。
在这种情况下可能有什么问题?如何正确处理大量并行数据库 IO?
附言
假设每个请求只有一个连接。我使用配置了 WebSessionContext 的 nhibernate。
我像这样初始化我的 NHibernate 会话:
ISession session = null;
//factory variable is session factory
if (CurrentSessionContext.HasBind(factory))
{
session = factory.GetCurrentSession();
if (session == null)
CurrentSessionContext.Unbind(factory);
}
if (session == null)
{
session = factory.OpenSession();
CurrentSessionContext.Bind(session);
}
return session;
在 HttpApplication.EndRequest 我像这样发布它:
//factory variable is session factory
if (CurrentSessionContext.HasBind(factory))
{
try
{
CurrentSessionContext.Unbind(factory)
.Dispose();
}
catch (Exception ee)
{
Logr.Error("Error uninitializing session", ee);
}
}
据我所知,每个请求生命周期应该只有一个连接。在处理请求时,代码按顺序执行(ASP.NET MVC 3)。所以看起来这里不可能有任何并发性。我可以得出结论,在这种情况下没有共享连接吗?