#c# #sql-server-2005 #nhibernate
#c# #sql-server-2005 #nhibernate
Вопрос:
Я хочу указать определенный тайм-аут команды (или LOCK_TIMEOUT) для SQL, и как только это время истекает, в 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 server мы использовали для достижения этого следующий 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. Пожалуйста, помогите мне добиться этого.
Заранее спасибо за вашу помощь.
Комментарии:
1. В вашем коде C # указан 5-секундный тайм-аут, в то время как в SQL он равен 0,5 секунды.
Ответ №1:
Для достижения пессимистической блокировки вам необходимо получить сведения об объекте с помощью 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. Привет @ NRao, решение работает для меня. Пожалуйста, дайте мне знать, как также получить блокировку для нескольких полей.
2. Не был бы LockMode. Принудительно в исходном коде уже выполняется пессимистическая блокировка?
Ответ №2:
Интересно, могли бы вы адаптировать этот подход к своим целям? Конечно, это не было бы автоматическим. и это означало бы, что переданное в resourceName, вероятно, должно быть конкатенацией вашего типа объекта и его PK.
В качестве альтернативы, command_timeout выглядит многообещающе, но я не вижу способа сделать это (для обновлений) каким-либо иным способом, кроме общесистемного.