Nhibernate设置命令和悲观锁定的查询超时时间

时间:2011-11-12 04:54:17

标签: c# sql-server-2005 nhibernate

我希望为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显示锁定超时或命令超时信息。请帮我实现这个目标。
在此先感谢您的帮助。

2 个答案:

答案 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看起来很有希望,但我无法以系统范围以外的任何方式看到(更新)的方法。