Взгляните на эту ветку: http://n2cms.codeplex.com/Thread/View.aspx?ThreadId=85016
В основном то, что он говорит как возможную причину этого исключения:
2010-02-17 21: 01: 41,204 1 WARN NHibernate.Util.ADOExceptionReporter - System.Data.SqlClient.SqlException: журнал транзакций для базы данных «имя базы данных» заполнен. Чтобы узнать, почему пространство в журнале нельзя использовать повторно, см. Столбец log_reuse_wait_desc в sys.databases
Поскольку размер журнала транзакций пропорционален объему работы, проделанной во время транзакции, возможно, вам следует рассмотреть возможность помещения границ транзакции через обработку обработчиками команд команд в части транзакций, связанных с записью. Затем в сеансе # X вы загрузите состояние, которое хотите изменить, измените его и зафиксируйте, все как одну единицу работы в #X.
Что касается чтения, то у вас может быть другой ISession # Y, который читает данные; этот ISession может использоваться для пакетного чтения внутри, например RepeatableRead или что-то подобное с функцией Futures и может просто читать из кеша (если это действительно костыль). Это может помочь вам избавиться от «ошибок», которых нет; livelocks, взаимоблокировки и транзакции-жертвы.
Проблема с использованием транзакции на запрос заключается в том, что ваш ISession получает много данных бухгалтерского учета во время вашей работы, и все они являются частью транзакции. Следовательно, база данных отмечает данные (роли, столбцы, таблицы и т. Д.) Как участвующие в транзакции, в результате чего граф ожидания охватывает «сущности» (в смысле базы данных, а не в смысле DDD), которые на самом деле не являются частью транзакционной границы команды, принятой вашим приложением.
Для записи (другие люди гуглили), у Фабио был сообщение, посвященное работе с исключениями на уровне данных. Цитируя часть его кода;
public class MsSqlExceptionConverterExample : ISQLExceptionConverter
{
public Exception Convert(AdoExceptionContextInfo exInfo)
{
var sqle = ADOExceptionHelper.ExtractDbException(exInfo.SqlException) as SqlException;
if(sqle != null)
{
switch (sqle.Number)
{
case 547:
return new ConstraintViolationException(exInfo.Message,
sqle.InnerException, exInfo.Sql, null);
case 208:
return new SQLGrammarException(exInfo.Message,
sqle.InnerException, exInfo.Sql);
case 3960:
return new StaleObjectStateException(exInfo.EntityName, exInfo.EntityId);
}
}
return SQLStateConverter.HandledNonSpecificException(exInfo.SqlException,
exInfo.Message, exInfo.Sql);
}
}
- 547 - это номер исключения для конфликта ограничений.
- 208 - это номер исключения для недопустимого имени объекта в SQL.
- 3960 - это номер исключения для транзакции изоляции моментального снимка, прерванной из-за конфликта обновления.
Так что, если вы сталкиваетесь с проблемами параллелизма, подобными описанным вами; помните, что они сделают ваш ISession недействительным и вам придется обращаться с ними, как указано выше.
Часть того, что вы, возможно, ищете, - это CQRS, где у вас есть отдельные стороны чтения и записи. Это может помочь: http://abdullin.com/cqrs/, http://cqrsinfo.com.
Итак, чтобы подвести итог; ваши проблемы могут быть связаны с тем, как вы обрабатываете свои транзакции. Также попробуйте запустить select log_wait_reuse_desc from sys.databases where name='MyDBName'
и посмотрите, что это вам даст.
person
Henrik
schedule
20.11.2010