Существуют ли исключения SqlException, которые выдают, но все равно фиксируют свои данные?

Недавно я столкнулся с ошибкой:

System.Data.SqlClient.SqlException: журнал транзакций для базы данных «mydatabase» заполнен. Чтобы узнать, почему пространство в журнале нельзя использовать повторно, см. столбец log_reuse_wait_desc в sys.databases.

на одной из моих служб Windows. Он должен повторить попытку после обнаружения исключения Sql, чего я не ожидал, так это того, что казалось, что данные все еще проходят (кстати, я использую SqlBulkCopy), независимо от того, что он генерирует исключение. Я никогда не сталкивался с этим сценарием раньше.

Я хотел бы знать, есть ли другие сценарии, в которых может произойти подобное, и вообще возможно ли это вообще?

ИЗМЕНИТЬ:

System.Data.UpdateException: произошла ошибка при обновлении записей. Подробнее см. InnerException. ---> System.Data.SqlClient.SqlException: журнал транзакций для базы данных «MY_DB» заполнен. Чтобы узнать, почему пространство в журнале нельзя использовать повторно, см. столбец log_reuse_wait_desc в sys.databases в System.Data.SqlClient.SqlConnection.OnError (исключение SqlException, логическое breakConnection) в System.Data.SqlClient.SqlInternalConnection.OnError (исключение SqlException , логическое значение breakConnection) в System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) в System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultS bulkCopyDataClientjState at System.Data.SqlClient.TdsParser.State, TObjectdsParserber .SqlDataReader.ConsumeMetaData() в System.Data.SqlClient.SqlDataReader.get_MetaData() в System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) в System.Data.SqlClient.SqlCommand.RunCommandBehExecute( cmdBehavior, RunBehavior runBehavior, логическое значение returnStream, логическое значение asyn c) в System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, метод String, результат DbAsyncResult) в System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runStreamBehavior, String метод return ) в System.Data.SqlClient.SqlCommand.ExecuteReader (поведение CommandBehavior, метод String) в System.Data.SqlClient.SqlCommand.ExecuteDbDataReader (поведение CommandBehavior) в System.Data.Common.DbCommand.ExecuteReader (поведение CommandBehavior) в System.Data .Mapping.Update.Internal.DynamicUpdateCommand.Execute(переводчик UpdateTranslator, подключение EntityConnection, Dictionary2 identifierValues, List1 generateValues) в System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, адаптер IEntityAdapter) --- Конец внутренней трассировки стека исключений --- в System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityState Менеджер состояний, адаптер IEntityAdapter) в System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) в System.Data.Objects.ObjectContext.SaveChanges(логическое значение acceptChangesDuringSave) в System.Data.Objects.ObjectContext.SaveChanges()

PS. Если кто-нибудь знает код ошибки для приведенного выше исключения, это также очень поможет.


person Jonn    schedule 29.04.2010    source источник


Ответы (2)


если это вообще вообще возможно?

Да, это возможно. Это зависит от того, что делает ваш код управления транзакциями в случае исключения. Например:

Connection connection = ConnectionFactory.create();

try {
    DoWorkOn(connection);
}
catch (Exception e) {
    Log.Message("SQL Problem", e);
}
finally {
    connection.commit();
}

... всегда будет пытаться совершить. Это поведение встроено в некоторые известные библиотеки управления транзакциями (J2EE специфицирует это поведение для исключений приложений).

Я менее знаком с .NET - если вы опубликуете полную трассировку стека, кто-нибудь сможет дать вам лучший ответ на основе используемого программного обеспечения для управления транзакциями.

person richj    schedule 29.04.2010
comment
Я отредактировал его, чтобы включить трассировку стека. Странный. Не имеет большого смысла, если он сигнализирует об отказе через исключение, но все равно фиксируется. - person Jonn; 30.04.2010
comment
В J2EE это связано с повторным использованием соединения на границе транзакции между Enterprise Java Beans (например, с атрибутом транзакции REQUIRED). Если второй EJB генерирует исключение, первый EJB может захотеть перехватить исключение и повторить попытку или выполнить восстановление, чтобы транзакция завершилась успешно, несмотря на исключение. Если бы исключение привело к тому, что транзакция была помечена для отката, тогда было бы невозможно закодировать этот тип поведения повторной попытки/восстановления. - person richj; 30.04.2010
comment
Спасибо за трассировку стека. К сожалению, это не говорит мне так много, как я надеялся. Я надеялся получить подсказку, которая укажет на класс диспетчера транзакций, который выполняет фиксацию. С этой информацией мы могли либо прочитать документацию (если она из сторонней библиотеки), либо посмотреть код (если это собственный код). - person richj; 30.04.2010

Команда SQL может привести к ошибке тайм-аута, но все равно произойдет. Вы должны планировать UPDATE и DELETE таким образом, чтобы их можно было вызывать много раз, но выполнять изменение только один раз. Например

UPDATE MyTable SET DataField=1,LastChanged=GETUTCDATE()  
   WHERE PrimaryKeyField=x AND DataField=0

Таким образом, если DataField больше не имеет ожидаемого значения, UPDATE ничего не сделает и оставит поле LastChanged без изменений.

person billpg    schedule 20.07.2011