Fluent NHibernate - 需要多程序访问单个延迟加载的 SQLite 数据库
我正在开发一个项目,其中有多个程序共享一个延迟加载的 SQLite 数据库文件,使用 Fluent Nhibernate(自动映射)作为数据访问层。
我开发的第一个程序(我们称之为程序 1)始终保持会话打开,并且延迟加载工作得很好。
当我运行程序 2,并尝试在程序 1 运行时从程序 2 写入数据库时,此方法失败 - 我遇到“数据库锁定”异常。
我通过在程序 1 启动后关闭会话来解决这个问题 - 例如,
private ISessionFactory _sessionFactory;
private ISession _session;
_sessionFactory = Database.CreateSessionFactory();
_session = _sessionFactory.OpenSession();
_session.BeginTransaction();
// ... read the database here
_session.Close();
当然,当用户从用户界面中选择不同的数据数据集时,这会破坏程序 1 中的延迟加载 - 这是我所期望的。
我以为只要用户选择新数据,我就可以再次打开会话,然后再次关闭它 - 例如,
if ( !_session.IsOpen )
_session = _sessionFactory.OpenSession();
if ( !_session.IsConnected )
_session.Reconnect();
_session.BeginTransaction();
// ... read the database here
_session.Close();
但到目前为止,还无法使其正常工作。当我尝试读取数据时,即使我刚刚打开了一个会话,我也会收到“没有会话,或会话已关闭”异常。 (连接测试只是一个实验,因为异常跟踪说了一些关于断开连接时抛出惰性异常的信息,但它没有帮助)
我做错了什么?
I'm developing a project that has multiple programs that share a single, lazy loaded SQLite database file, using Fluent Nhibernate (Auto Mapping) as the data access layer.
The first program I developed (let's call it Program 1) kept the Session open all the time, and lazy loading worked fine.
This approach failed when I got Program 2 running, and tried to write to the database from Program 2 while Program 1 was running - I got "database locked" exceptions.
I got around this by closing the Session after Program 1 starts up - e.g.
private ISessionFactory _sessionFactory;
private ISession _session;
_sessionFactory = Database.CreateSessionFactory();
_session = _sessionFactory.OpenSession();
_session.BeginTransaction();
// ... read the database here
_session.Close();
Of course, this broke lazy loading in Program 1 when the user selected a different data data set from the user interface - which I had expected.
I thought I would be able to just open the Session again whenever the user selected new data, and then close it again - e.g.
if ( !_session.IsOpen )
_session = _sessionFactory.OpenSession();
if ( !_session.IsConnected )
_session.Reconnect();
_session.BeginTransaction();
// ... read the database here
_session.Close();
But so far, have not been able to get this to work. I get "no session, or session was closed" exception when I try to read the data, even though I've just opened a session. (The test for the connection was just an experiment, because the exception trace said something about throwing lazy exceptions when disconnected, but it didn't help)
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否可以构建一个由第一个应用程序启动的服务层来调用它(或者如果您在 Windows 盒子上则注册为 Windows 服务),然后让每个人都调用该服务以从中获取数据?
我不是在谈论拥有一个单独的服务器,只是您的程序调用的一个单独的服务。
Is it possible for you to build a service layer which is initiated by the first app to call it (or registered as a windows service if you are on a windows box) and then have everyone call into that service to get their data from?
Im not talking about having a separate server, just a separate service that your programs call into.
在我因其他原因重构了一些会话管理代码后,“数据库锁定”异常神秘地消失了。 (主要的更改是使用事务来进行所有数据库访问,并确保所有事务和会话对象都得到正确处置 - 主要是将它们包含在“使用”块中)。
此链接讨论了由缺少 Dispose 引起的类似问题。我怀疑这可能是我的问题,但不确定。
另一个值得尝试的好来源是 数据库文件在 SQLite 提交期间被莫名其妙地锁定
无论如何,多个程序现在可以成功读取和写入单个共享 SQLite 数据库。
The "database locked" exceptions mysteriously disappeared after I refactored some of the session management code for other reasons. (The main changes were to use Transactions for ALL DB access, and to ensure all Transaction and Session objects were properly Disposed - mainly by enclosing them in "using" blocks).
This link discusses a similar problem that was caused by a missing Dispose. I suspect that may have been my problem, but am not sure.
Another good source of things to try is Database file is inexplicably locked during SQLite commit
In any case, multiple programs are now successfully reading and writing to a single shared SQLite database.