Посмотрите на эту тему:
http://n2cms.codeplex.com/Thread/View.aspx?ThreadId=85016
В основном то, что говорится как возможная причина этого исключения:
2010-02-17 21: 01: 41,204 1 ПРЕДУПРЕЖДЕНИЕ
NHibernate.Util.ADOExceptionReporter -
System.Data.SqlClient.SqlException:
Журнал транзакций для базы данных
'databasename' заполнено. Выяснить
почему пространство в журнале нельзя использовать повторно,
см. столбец log_reuse_wait_desc в
sys.databases
Поскольку размер журнала транзакций пропорционален объему работы, выполненной во время транзакции, возможно, вам следует обратить внимание на то, что вы должны поместить свои транзакционные границы между «обработкой» команд обработчиками команд в части записи транзакций. Затем, во время сеанса # X, вы загружаете состояние, которое хотите изменить, изменяете его и фиксируете, как одну единицу работы в # X.
Что касается сторон чтения, то у вас может быть другая ISession # Y, которая читает данные; эта сессия IS может использоваться для пакетного чтения, например RepeatableRead или что-то подобное с функцией Futures и может просто считывать данные из кэша (в действительности, это действительно костыль). Выполнение этого может помочь вам оправиться от «ошибок», которых нет; живые блокировки, взаимоблокировки и транзакции жертвы.
Проблема с использованием транзакции на запрос заключается в том, что ваша ISession получает много данных бухгалтерского учета, пока вы работаете, и все это является частью транзакции. Следовательно, база данных помечает данные (rols, cols, таблицы и т. Д.) Как участвующие в транзакции, в результате чего граф ожидания охватывает «сущности» (в смысле базы данных, а не в смысле 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 - номер исключения для транзакции изоляции моментального снимка, прерванной из-за конфликта обновления.
Так что, если вы сталкиваетесь с проблемами параллелизма, такими как то, что вы описываете; помните, что они сделают вашу сессию недействительной, и вам придется обращаться с ними, как описано выше.
Часть того, что вы можете искать, - это CQRS, где у вас есть отдельные стороны чтения и записи. Это может помочь: http://abdullin.com/cqrs/, http://cqrsinfo.com.
Итак, подведем итог; Ваши проблемы могут быть связаны с тем, как вы обрабатываете свои транзакции. Также попробуйте запустить select log_wait_reuse_desc from sys.databases where name='MyDBName'
и посмотреть, что он вам даст.