Похоже, ваша проблема связана с Column(Integer,primary_key = True,autoincrement = False, nullable=False)
. Посмотрите в документах сигнатуру функции для Column
. - первым аргументом для столбца должен быть столбец «имя», за которым следует столбец «тип».
Первый аргумент должен быть назван как «aya_id».
Запрос HQL DML выполнит ваше обновление без необходимости блокировки.
Это доступно в NHibernate 2.1, но пока отсутствует в справочной документации. Документация Java hibernate очень близка к реализации NHibernate.
Предполагая, что вы используете изоляцию ReadCommitted Isolation, вы можете безопасно прочитать свое значение обратно внутри транзакции.
With.Transaction (session, IsolationLevel.Serializable, delegate
{
session.CreateQuery( "update TarificationProfile t set t.AttestCounter = 1 + t.AttestCounter where t.id=:id" )
.SetInt32("id", tarificationProfileId)
.ExecuteUpdate();
nextNumber = session.CreateQuery( "select AttestCounter from TarificationProfile where Id=:id" )
.SetInt32("id", id )
.UniqueResult<int>();
}
В зависимости от имен таблиц и столбцов, сгенерированный SQL будет выглядеть следующим образом:
update TarificationProfile
set AttestCounter = 1 + AttestCounter
where Id = 1 /* @p0 */
select tarificati0_.AttestCounter as col_0_0_
from TarificationProfile tarificati0_
where tarificati0_.Id = 1 /* @p0 */
You could use isolation level "repeatable read" if you want to make sure that values you read from the database don't change during the transaction. But you have to do this in all critical transactions. Or you lock it in the critical reading transaction with an upgrade lock.
Если все, что вы читаете, выполняется с помощью IsolationLevel of Serializable и все записи также выполняются с помощью IsolationLevel of Serializable Я не понимаю, почему вам нужно самостоятельно блокировать строки базы данных.
Таким образом, сериализация сохраняет данные в безопасности, теперь у нас все еще есть проблема возможных мертвых блокировок ....
Если взаимоблокировки встречаются нечасто, просто поместите [start transaction, read, update, save] в Цикл повтора при возникновении тупиковой ситуации может быть достаточно хорошим.
В противном случае простой оператор «выберите для обновления», сгенерированный напрямую (например, не с помощью nhibernate), можно было бы использовать, чтобы остановить другую транзакцию, читающую строку, прежде чем она будет изменена.
Однако я продолжаю думать, что если частота обновления достаточно высока для получения большого количества взаимоблокировок, ORM может быть неправильным инструментом для обновления, или может потребоваться переработка схемы базы данных, чтобы избежать значения, которое необходимо прочитать / записано (например, вычисление при чтении данных)
Сомневаюсь, что это можно сделать из NHibernate. Лично я бы использовал хранимую процедуру, чтобы делать то, что вы пытаетесь выполнить.
Обновление: Учитывая продолжающиеся отрицательные голоса, я остановлюсь на этом подробнее. Фредерик спрашивает, как использовать подсказки блокировки, которые представляют собой специфичные для синтаксиса и реализации детали его базового механизма базы данных, из его уровня ORM. Это неправильный уровень для попытки выполнить такую операцию - даже если бы это было возможно (а это не так), вероятность того, что она когда-либо будет работать согласованно во всех базах данных, поддерживаемых NHibernate, исчезающе мала.
Замечательно, что возможное решение Фредерика не требовало упреждающих эксклюзивных блокировок (которые убивают производительность и, как правило, являются плохой идеей, если вы не знаете, что делаете), но мой ответ верен. Любой, кто сталкивается с этим вопросом и хочет выполнить исключительную блокировку при чтении из NHibernate - во-первых: не надо, во-вторых: если нужно, используйте хранимую процедуру или SQLQuery.