Вот некоторая предыстория: наш сайт периодически падает до такой степени, что приходится перезапускать IIS; это почти всегда происходит в течение часа после исправления DLL (мы используем проект веб-сайта, а не проект веб-приложения, поэтому каждая страница ASPX является отдельной DLL).
Проведя некоторые исследования, я обнаружил, что наш DAL для доморощенных при отладке может привести к тому, что встроенный веб-сервер с Visual Studio фактически перестанет работать и будет отключен, если он обнаружит ошибку SQL в хранимой процедуре (я имею в виду это). не только выдаст исключение, которое отображается в браузере, но и фактически скажет, что веб-сервер обнаружил ошибку и должен быть закрыт!)
При дальнейшем копании ошибка, по-видимому, связана с использованием транзакций для всего (включая операторы Select) в DAL. Кажется, что происходит вот что:
- Пытается выполнить хранимую процедуру, сбой хранимой процедуры из-за отсутствия / недопустимого столбца или другой ошибки.
- Код приложения ловит ошибку и сбрасывает ее (плохо, да, но я этого не писал).
- Транзакция пытается выполнить фиксацию, несмотря на исключение, получает
NullReferenceException
в строке transaction.Commit()
(похоже, в свойстве Connection
, поскольку существует объект транзакции). Кроме того, этот NullRef, похоже, не может быть перехвачен (я попробовал демо-версию, в которой принудительно произошел сбой с недопустимым Sproc, и NullRef никогда не был перехвачен, даже несмотря на то, что при выводе ошибки его тип был System.NullReferenceException
)
- Транзакция выдает ошибку, которая говорит что-то вроде «Транзакция завершена и больше не может использоваться».
- ??? но веб-сервер VS падает. Отладка этой части, кажется, зависает над вышеупомянутым исключением, никогда не покидая метод.
Теперь я не знаю, приводит ли это к аварийному завершению IIS, но это кажется довольно подозрительным, и в любом случае это явная ошибка.
Не имея дело с транзакциями ранее и имея только базовую идею о них, мой первый вопрос: , почему транзакция все еще пытается зафиксировать после создания исключения? Мой второй вопрос: как исправить неудачную фиксацию и предположительно бесконечный цикл исключений до тех пор, пока сервер не умрет. Не имеет ли смысла добавлять что-то подобное (метод принимает параметр SqlTransaction с именем transaction
):
catch (SqlException se)
{
if (transaction != null)
{
transaction.Rollback();
}
throw;
}
Исправит ли это небольшое изменение постоянный цикл исключения, который, как мне кажется, приводит к сбою IIS? Сам DAL чрезвычайно хрупок и используется конкретно в сотнях файлов, поэтому я не могу правильно переписать его с нуля.
РЕДАКТИРОВАТЬ Весь кодовый блок такой (опять же, унаследованный код - используется старый помощник блока доступа к данным Microsoft):
public static DataSet ExecuteDatasetStoredProc(SqlConnection conn, String storedProcName, SqlTransaction transaction, params SqlParameter[] storedProcParms)
{
try
{
// Execute the stored proc
if (transaction != null)
{
return SqlHelper.ExecuteDataset(transaction, CommandType.StoredProcedure, storedProcName, storedProcParms);
}
else
{
return SqlHelper.ExecuteDataset(conn, CommandType.StoredProcedure, storedProcName, storedProcParms);
}
}
catch (SqlException se)
{
throw new ApplicationException("Error calling " + storedProcName + ". " + se.Message, se);
}
}
Однако, если блок catch выполняет транзакцию, она все еще пытается зафиксировать, и это, кажется, вызывает зависания.