NHibernate с SQL Server - как обрабатывать следующий новый тип среды - PullRequest
0 голосов
/ 02 марта 2010

У меня есть приложение (ASP.NET MVC), которое использует метод Next New, чтобы получить следующую новую часть работы. Пользователь нажимает кнопку «Next New», и мой код NHibernate отправляет следующую работу с активным статусом. Поскольку количество пользователей увеличилось, мы столкнулись с проблемой, когда 2 пользователя могут получить одну и ту же работу. Это происходит даже при том, что я обернул мои вызовы SELECT и UPDATE в транзакцию.

Я также попытался установить для транзакции значение IsolationLevel из RepeatableRead, но это просто вызвало бы исключение TransactionException, когда 2 пользователя пытаются получить доступ к данным одновременно.

Вот процесс, который я сейчас использую:

  1. Получить следующий рабочий объект
  2. Обновите объект, чтобы показать, что он отложен, и сохраните его в БД
  3. Отображение работы пользователю

Вот код, который я сейчас использую:

    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;
        }
    }

Критерий - это объект DetachedCriteria, который просто ищет активные учетные записи и сортирует их по убыванию по дате.

У кого-нибудь есть какие-либо предложения о том, как я мог бы сделать эту работу?

1 Ответ

0 голосов
/ 14 марта 2010

Обновление:

Я решил эту проблему, отправив через пользовательский оператор 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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...