我有一个使用iBATIS.NET库的网络应用程序。
使用XmlDocument配置DAO,因此代码与文档中显示的代码非常相似:
XmlDocument anXmlDoc = someSupportClass.GetDynamicXmlDocument();
DomDaoManagerBuilder builder = new DomDaoManagerBuilder();
builder.Configure(anXmlDoc);
文档说明如下:
可以识别从dao.config文件构建的DaoManager实例 配置文件中包含的所有上下文。该 context基本上将DAO实现与会话捆绑在一起 处理程序。 DaoManager知道哪些DAO和会话处理程序属于 哪个背景。当您从DaoManager请求DAO实例时, 将提供适当的会话处理程序。因此,那里 不需要直接访问上下文或会话处理程序。你的DAO 知道它是如何工作的。
这似乎不是真的。在线程进程中,随机抛出以下异常:
WebSessionStore:无法获取对HttpContext的引用 IBatisNet.DataAccess.SessionStore.WebSessionStore.ObtainSessionContext() 在 IBatisNet.DataAccess.SessionStore.WebSessionStore.get_LocalSession()
在IBatisNet.DataAccess.DaoManager.IsDaoSessionStarted()at IBatisNet.DataAccess.Configuration.DaoProxy.Intercept(IInvocation invocation,Object [] arguments)
应用程序可以一次运行好几天甚至几个月,但每隔一段时间就抛出一次此异常。我可以在任何地方找到的唯一解决方案是将SessionStore换成HybridWebThreadSessionStore
(mentioned here)。
如上文所述,这不是必需的。如果我想强制它,我将如何覆盖由DomDaoManagerBuilder
创建的SessionStore?
答案 0 :(得分:1)
问题似乎是由应用程序启动时iBatis.NET框架中的竞争条件引起的。如果在单独的线程上调用数据库之前在主线程上调用数据库,那么单独的线程将引发错误,因为它们没有在SessionStore中存储HttpContext。
基本上它去了Startup -> db call on main thread -> db call on separate thread
应该是Startup -> db call on separate thread -> db call on main thread
基本上我只是更改了事件触发的顺序,以确保线程上的db调用至少在主线程上发生任何事情之前被调用一次。
This post describes the same problem
设置
在我的Global.asax中,我使用Timer启动后台进程 类。这个Timer类使用的是delgate DoTimerBasedStuff() 定期打电话。 DoTimerBasedStuff()方法访问两个 不同的数据库,MySQL和SQL Server。两者都设置正确 使用他们的MySQLMapper和SQLServerMapper类。
除了这些后台线程之外,还有应用程序 有一个Web前端,使用典型的.aspx访问这两个数据库 从Page继承的页面和类。没什么好看的。
问题
如果使用浏览器转到index.aspx启动应用程序 (此页面不执行任何数据库操作但触发Global.asax)并且没有 在第一次调用DoTimerBasedStuff()之前会执行其他操作 一切都很好,后台进程和网络用户都是 精细。 IBatis做的一切都很正确。
但是如果我通过转到index.aspx然后启动应用程序 立即通过访问数据库的网络做一些工作(之前 执行DoTimerBasedStuff()),DoTimerBasedStuff()方法具有 访问HttpContext时出现问题,并出现以下错误:
异常:WebSessionStore:无法获取对HttpContext的引用 在IBatisNet.DataMapper.SessionStore.WebSessionStore.ObtainSessionContext() 在IBatisNet.DataMapper.SessionStore.WebSessionStore.get_LocalSession() 在IBatisNet.DataMapper.SqlMapper.QueryForObject(String ...
答案 1 :(得分:0)
发生错误是因为您在不同的线程中运行ibatis。 您可以在对数据库进行查询之前使用HybridWebThreadSessionStore的新实例。
var map = new Hashtable
{
{ "FilterA", "MyFilter" }
};
SqlMap.SessionStore = new HybridWebThreadSessionStore(SqlMap.Id);
var listadoJobs = SqlMap.QueryForList<EventoJob>(SbsIbatisConstantes.ListarJobs, map).ToList();
您可以查看此引用Here
对我有用。