.net NHibernate与SQL Server-如何处理下一种新类型的环境

.net NHibernate与SQL Server-如何处理下一种新类型的环境,.net,sql-server,nhibernate,.net,Sql Server,Nhibernate,我有一个应用程序ASP.NET MVC,它使用下一个新方法来获得下一个新工作。用户单击下一个新按钮,我的NHibernate代码将以活动状态获取下一项工作。随着用户数量的增加,出现了一个问题,即两个用户可以获得相同的工作。即使我已将SELECT和UPDATE调用包装到事务中,也会发生这种情况 我还尝试将事务设置为RepeatableRead的IsolationLevel,但这只会在两个用户同时尝试访问数据时引发TransactionException 以下是我目前使用的流程: using

我有一个应用程序ASP.NET MVC,它使用下一个新方法来获得下一个新工作。用户单击下一个新按钮,我的NHibernate代码将以活动状态获取下一项工作。随着用户数量的增加,出现了一个问题,即两个用户可以获得相同的工作。即使我已将SELECT和UPDATE调用包装到事务中,也会发生这种情况

我还尝试将事务设置为RepeatableRead的IsolationLevel,但这只会在两个用户同时尝试访问数据时引发TransactionException

以下是我目前使用的流程:

    using (var txn = _repository.Session.BeginTransaction(IsolationLevel.RepeatableRead))
    {
        try
        {
            newAccount = _repository.FindFirstWithLock(criteria, LockMode.Read);

            newAccount.QueueStatus = pendingStatus;
            _repository.Save(newAccount);    

            txn.Commit();
        }
        catch (Exception)
        {
            txn.Rollback();
            throw;
        }
    }
获取下一个工作对象 更新对象以显示其已挂起并保存到数据库 向用户显示工作 以下是我当前使用的代码:

    using (var txn = _repository.Session.BeginTransaction(IsolationLevel.RepeatableRead))
    {
        try
        {
            newAccount = _repository.FindFirstWithLock(criteria, LockMode.Read);

            newAccount.QueueStatus = pendingStatus;
            _repository.Save(newAccount);    

            txn.Commit();
        }
        catch (Exception)
        {
            txn.Rollback();
            throw;
        }
    }
criteria是一个DetachedCriteria对象,它只查找活动帐户并按日期属性降序排序

有人对我如何完成这项工作有什么建议吗?

更新:

我通过发送自定义T-SQL语句、锁定当前行并读取已锁定行(如果其中一行已被锁定)来解决此问题:

    using (var txn = _accountRepository.Session.BeginTransaction())
    {
        try
        {

            updateResult = _accountRepository.Session.CreateSQLQuery(
                SqlQueries.GetNextQueueItem(orderByClause, strategyId, languageId, tomorrow, userName)).ExecuteUpdate();
            txn.Commit();
        }
        catch (Exception)
        {
            txn.Rollback();
            throw;
        }
    }
SQL查询如下所示:

UPDATE       ACCOUNTS 
            SET          QUEUE_STATUS_ID = 2 
                        ,OWNED_BY = '[username]' 
                        ,OWNERSHIP_DATE = GETDATE() 
            FROM        ACCOUNTS   
            WHERE   CUSTOMER_ACCOUNT_ID = 
                            ( 
                                SELECT      TOP(1) CUSTOMER_ACCOUNT_ID 
                                FROM        FIT_PAYPAL_ACCOUNTS  WITH(ROWLOCK, READPAST, UPDLOCK) 
                                WHERE           STRATEGY_ID = 999
                                            AND NEXT_WORK_DATE < '3/1/2010' 
                                            AND STATUS_ID = 0