首先让我说明一下我想要实现的目标。我有一张桌子,里面装满了工作。有一个 Web 服务,其方法允许更改作业数据,称为SaveJob
。此方法检索作业及其所有数据,对新数据运行验证(这需要对其他表进行一些数据库查询),然后将其保存回数据库。有点慢。大约一秒钟。
偶尔会发生两种情况SaveJob
同一工作上的调用会紧密相连,并且它们会互相冲突。目前,这是唯一的网络服务器,但我希望我的解决方案网络场兼容,因此即使我知道如何使用单例解决此问题,我还是希望由数据库处理锁。
问题是,当第二个 SaveJob 调用尝试读取已被另一个 SaveJob 调用更改的作业时,我是否可以使用 NHibernate 和 SQL Server 数据库锁来阻止第二个 SaveJob 调用?
我相信答案是肯定的,但我不太确定如何去做。我已阅读有关的文档ISession.Lock()
我相信我需要的是使用NHibernate.LockMode.Upgrade
我的下一个问题是这个锁什么时候释放?
我假设它在事务提交时被释放,但我找不到任何明确说明这一点的文档。
但是,如果是这种情况,那么有没有办法让我打开另一个事务并运行一些查询,而不关闭我最初抓住这份工作时开始的事务?还是我have在一笔交易中完成这一切?
首先,我建议不要跨多个线程使用单个事务,因为 ISession 本身不是线程安全的。
当你使用LockMode.Upgrade
在会议上,或在session.Get()
,NHibernate会发出一个select with (rowlock)
检索实体时的语句(详细信息可能取决于数据库类型和配置)。如果该对象之前被另一个线程检索过,则当前线程将等待,直到锁被释放或超时到期。当锁本身被释放时update
语句执行于transaction.Commit()
. Using LockMode.UpgradeNoWait
提供类似的功能,只不过它不会等待,并且在获取锁定时会失败。
This 阿延德的帖子 http://ayende.com/blog/3946/nhibernate-mapping-concurrency还有一些关于 SQL NHibernate 发出的信息session.Lock()
.
您可以阅读有关不同类型的锁的信息NHibernate 文档第 11 章第 6 节 http://nhforge.org/doc/nh/en/index.html#transactions-locking.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)