简体   繁体   English

NHibernate / SQL Server中不同会话中的并行事务

[英]Parallel Transactions in distinct Session in NHibernate / SQL Server

we are building a WinForms desktop application which talks to an SQL Server through NHibernate. 我们正在构建一个WinForms桌面应用程序,该应用程序通过NHibernate与SQL Server通讯。 After extensive research we settled on the Session / Form strategy using Ninject to inject a new ISession into each Form (or the backing controller to be precise). 经过大量研究,我们确定了会话/表单策略,使用Ninject将新的ISession注入每个表单(或精确地说是支持控制器)。 So far it is working decently. 到目前为止,它运行良好。

Unfortunately the main Form holds a lot of data (mostly read-only) which gets stale after some time. 不幸的是,主窗体包含许多数据(大多数是只读的),一段时间后会过时。 To prevent this we implemented a background service (really just a seperate class) which polls the DB for changes and issues an event which lets the main form selectively update the changed rows. 为了避免这种情况,我们实现了一个后台服务(实际上只是一个单独的类),该服务轮询数据库中的更改并发出一个事件,该事件使主窗体有选择地更新更改的行。

This background service also gets a separate session to minimize interference with the other forms. 此后台服务还获得了一个单独的会话,以最大程度地减少对其他表单的干扰。 Our understanding was that it is possible to open a transaction per session in parallel as long as they are not nested. 我们的理解是,只要不嵌套每个会话,就可以并行打开一个事务。

Sadly this doesn't seem to be the case and we either get an ObjectDisposedException in one of the forms or the service (because the service session used an existing transaction from on of the forms and committed it, which fails the commit in the form or the other way round) or we get an InvalidOperationException stating that "Parallel transactions are not supported by SQL Server". 遗憾的是,似乎不是这种情况,我们要么以其中一种形式获取表单,要么以服务形式获取ObjectDisposedException (因为服务会话从表单中的on使用现有事务并将其提交,这导致表单或表单无法提交) InvalidOperationException ),或者我们收到一个InvalidOperationException声明“ SQL Server不支持并行事务”。

Is there really no way to open more than one transaction in parallel (across separate sessions)? 真的没有办法同时(在不同的会话中)同时打开多个事务吗? And alternatively is there a better way to update stale data in a long running form? 或者,是否有更好的方法可以长时间运行更新旧数据?

Thanks in advance! 提前致谢!

I'm pretty sure you have messed something up, and are sharing either session or connection instances in ways you did not intend. 我很确定您搞砸了,并以您不希望的方式共享会话或连接实例。

It can depend a bit on which sort of transactions you use: 这可能取决于您使用哪种交易:

  • If you use only NHibernate transactions ( session.BeginTransaction() ), each session acts independently. 如果仅使用NHibernate事务( session.BeginTransaction() ),则每个会话都独立运行。 Unless you do something special to insert your own underlying database connections (and made an error there), each session will have their own connection and transaction. 除非您进行一些特殊的操作以插入自己的基础数据库连接(并在那里出错),否则每个会话将具有自己的连接和事务。
  • If you use TransactionScope from System.Transactions in addition to the NHibernate transactions, you need to be careful about thread handling and the TransactionScopeOption. 如果除了NHibernate事务之外还使用System.Transactions中的TransactionScope,则需要注意线程处理和TransactionScopeOption。 Otherwise different parts of your code may unexpectedly share the same transaction if a single thread runs through both parts and you haven't used TransactionScopeOption.RequiresNew. 否则,如果单个线程贯穿两个部分,并且您没有使用TransactionScopeOption.RequiresNew,则代码的不同部分可能会意外共享同一事务。

Perhaps you are not properly disposing your transactions (and sessions)? 也许您没有正确处理事务(和会话)?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM