我正在使用 ASP.NET MVC 2 构建一个小型 Web 应用程序,并使用 db4o 作为数据存储。
我添加了一个 HttpModule——按照 the example here — 为应用程序提供对 db4o 数据库的访问权限,并且在我的 VS2008 ASP.NET 开发服务器下的开发计算机上一切都运行良好。
但是,当我将应用程序部署到 Web 主机并尝试访问它时,我在 HttpModule 尝试打开数据库文件的行处收到 DatabaseFileLockedException
。但不应该有任何其他东西访问该文件;事实上,在应用程序第一次运行时,只有在引发此异常时才会创建它。
Web 主机的服务器在 Windows Server 2008 上运行 IIS 7,并且应用程序在完全信任下运行。它是一个子应用程序,以防产生任何影响。
我无法弄清楚为什么此错误发生在实时服务器上,但不在我的开发服务器本地发生。谁能帮助我或建议我下一步应该做什么?
最佳答案
这是示例代码中的错误。它假设 HttpModule.Init 仅被调用一次,但这不一定是真的。根据应用程序的配置方式,它可以被多次调用。要解决此问题,请检查 HttpModule-Handler 实例是否已存在:
using System;
using System.Configuration;
using System.Web;
using Db4objects.Db4o;
namespace Db4oDoc.WebApp.Infrastructure
{
public class Db4oProvider : IHttpModule
{
private const string DataBaseInstance = "db4o-database-instance";
private const string SessionKey = "db4o-session";
// #example: open database when the application starts
public void Init(HttpApplication context)
{
if (null==HttpContext.Current.Application[DataBaseInstance])
{
HttpContext.Current.Application[DataBaseInstance] = OpenDatabase();
}
RegisterSessionCreation(context);
}
private IEmbeddedObjectContainer OpenDatabase()
{
string relativePath = ConfigurationSettings.AppSettings["DatabaseFileName"];
string filePath = HttpContext.Current.Server.MapPath(relativePath);
return Db4oEmbedded.OpenFile(filePath);
}
// #end example
// #example: close the database when the application shuts down
public void Dispose()
{
IDisposable toDispose = HttpContext.Current.Application[DataBaseInstance] as IDisposable;
if (null != toDispose)
{
toDispose.Dispose();
}
}
// #end example
// #example: provide access to the database
public static IObjectContainer Database
{
get { return (IObjectContainer)HttpContext.Current.Items[SessionKey]; }
}
// #end example
// #example: A object container per request
private void RegisterSessionCreation(HttpApplication httpApplication)
{
httpApplication.BeginRequest += OpenSession;
httpApplication.EndRequest += CloseSession;
}
private void OpenSession(object sender, EventArgs e)
{
IEmbeddedObjectContainer container =
(IEmbeddedObjectContainer)HttpContext.Current.Application[DataBaseInstance];
IObjectContainer session = container.OpenSession();
HttpContext.Current.Items[SessionKey] = session;
}
private void CloseSession(object sender, EventArgs e)
{
if (HttpContext.Current.Items[SessionKey] != null)
{
IObjectContainer session = (IObjectContainer)HttpContext.Current.Items[SessionKey];
session.Dispose();
}
}
// #end example
}
}
作为替代方案,您可以使用 Global.apsx 中的 Application_Start,它肯定只被调用一次。
关于c# - 尝试在 ASP.NET MVC 应用程序中打开 db4o 数据库时,是什么导致此 DatabaseFileLockedException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3435654/