我希望为SQL指定一个特定的命令超时(或LOCK_TIMEOUT),一旦达到超时,就必须在nHibernate中引发异常(或警告)。
以下是我编写的伪代码示例:
using (var session = sessionFactory.OpenSession()) {
using (var sqlTrans = session.BeginTransaction()) {
ICriteria criteria = session.CreateCriteria(typeof(Foo));
criteria.SetTimeout(5); //Here is the specified command timout, eg: property SqlCommand.CommandTimeout
Foo fooObject = session.Load<Foo>(primaryKeyIntegerValue, LockMode.Force);
session.SaveOrUpdate(fooObject);
sqlTrans.Commit();
}
}
在SQL服务器中,我们使用以下SQL实现此目的:
BEGIN TRAN
SET LOCK_TIMEOUT 500
SELECT * FROM Foo WITH (UPDLOCK, ROWLOCK) WHERE PrimaryKeyID = 1000001
如果PrimaryKeyID行已在其他事务中锁定,则SQL Server将显示以下错误消息:
Msg 1222, Level 16, State 51, Line 3
Lock request time out period exceeded
同样,我希望使用nHibernate显示锁定超时或命令超时信息。请帮我实现这个目标。
在此先感谢您的帮助。
答案 0 :(得分:3)
要实现悲观锁定,您需要使用ICritiera获取对象的详细信息 修改后的代码如下:
using (var session = sessionFactory.OpenSession()) {
using (var sqlTrans = session.BeginTransaction()) {
ICriteria criteria = session.CreateCriteria<Foo>();
criteria.Add(Restrictions.Eq(fieldOnWhichYouWishToGetTheLock, fieldValue));
criteria.SetLockMode(LockMode.Upgrade);
criteria.SetTimeout(5);
Foo fooObject = (Foo)criteria.List<Foo>();
//Make the changes to foo object and save as usual.
}
}
答案 1 :(得分:0)
我想知道您是否可以根据自己的目的调整this approach?当然,它不会是自动的。并且这意味着传入的resourceName可能需要是您的实体类型和PK的串联。
或者,command_timeout看起来很有希望,但我无法以系统范围以外的任何方式看到(更新)的方法。