2016-04-14 5 views
0

Я получил это исключение Сообщ:Как я могу предотвратить превращение в тупик?

Transaction (Process ID 55) зашло в тупик на ресурсах блокировки с другим процессом и был выбран в качестве тупиковой жертвы.

Единственная строка моего кода, который был замешан в трассировке стека была последней здесь:

public static DataTable ExecuteSQLReturnDataTable(string sql, CommandType cmdType, params SqlParameter[] parameters) 
{ 
    using (DataSet ds = new DataSet()) 
    using (SqlConnection connStr = new SqlConnection(CPSConnStr)) 
    using (SqlCommand cmd = new SqlCommand(sql, connStr)) 
    { 
     cmd.CommandType = cmdType; 
     cmd.CommandTimeout = EXTENDED_TIMEOUT; 
     foreach (var item in parameters) 
     { 
      cmd.Parameters.Add(item); 
     } 

     try 
     { 
      cmd.Connection.Open(); 
      new SqlDataAdapter(cmd).Fill(ds); 

Это универсальный метод, который я использую для всех видов запросов; Я не изменил его недавно, и я никогда не видел этого конкретного исключения раньше.

Что я могу сделать, чтобы избежать повторного выброса этого исключения?

ответ

2

Вы можете поймать исключение тупиковой ситуации и повторить X раз, прежде чем сдаваться.

Нет никакого волшебного решения, чтобы избежать взаимоблокировок. Если SQL Server обнаруживает тупик, он собирается выбрать один из процессов, чтобы убить. В некоторых случаях у вас могут быть тупики, где ваш процесс был тем, кому посчастливилось продолжить.

Вы можете использовать SQL Profiler для захвата взаимоблокировок. Я должен был сделать это в прошлом, чтобы попытаться выяснить, что на самом деле вызывает тупики. Чем реже это происходит, тем сложнее отслеживать. В нашей тестовой среде мы просто создали тестовый код, чтобы забить базу данных с нескольких разных машин, чтобы попытаться вызвать тупик.

В нашем случае мы внесли некоторые изменения в наши индексы и модифицированные триггеры базы данных, чтобы максимально сократить взаимоблокировки. В конце концов, нам все равно пришлось выполнять повторные попытки как «на всякий случай».

1

Возможно, это помогло, если вы указали SQL, который был передан в ExecuteSQLReturnDataTable. Между тем читайте Minimizing Deadlocks.

Конечно, вам, возможно, придется посмотреть на все, что вносит вклад в тупик.

Смежные вопросы