2009-05-11 3 views
1

При использовании общего DbCommand для выполнения обновления он будет зависать неопределенно, если обновляемая строка заблокирована.Есть ли способ использовать общий DbCommand для асинхронного обновления?

Базовое соединение используется является поставщиком Oracle DevArt, в Devart.Data.Oracle.OracleConnection

не Установка DbCommand.CommandTimeOut имеет никакого эффекта на всех, Никогда не обновлять раз из.

DbCommand не реализует BeginExecuteNonQuery, поэтому, похоже, нет возможности использовать DbConnection/DbCommand асинхронным образом.

Я могу обойти это, используя OracleCommand Devart и BeginExecuteQuery, но это так.

Есть ли способ сделать это в общем виде?

упрощенный код оракула определенной логики:

public bool TestAsyncUpdateRowOracle(string key, OracleConnection con, string sql) 
{ 
    const int timoutIterations=10; 
    bool updateOk=false; 
    OracleCommand cmd = new OracleCommand(sql, con); 
    cmd.Parameters.Add(Util.CreateParameter(dbSrcFactory, DbType.String, 16, "key")); 
    cmd.CommandType = CommandType.Text; 
    cmd.Parameters[0].Value = key.ToString(); 

    IAsyncResult result = cmd.BeginExecuteNonQuery(); 
    int asyncCount = 0; 
    while (!result.IsCompleted) 
    { 
     asyncCount++; 
     if (asyncCount > timeoutIterations) 
     { 
      break; 
     } 
     System.Threading.Thread.Sleep(10); 
    } 

    if (result.IsCompleted) 
    { 
     int rowsAffected = cmd.EndExecuteNonQuery(result); 
     Console.WriteLine("Done. Rows affected: " + rowsAffected.ToString()); 
    } 
    else 
    { 
     try 
     { 
      cmd.Cancel(); 
      Console.WriteLine("Update timed out, row is locked"); 

     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.ToString()); 
      Console.WriteLine("Unable to cancel update"); 
     } 
    } 
    cmd.Dispose(); 
} 

ответ

2

К сожалению, нет никакого интерфейса или базового класса в ADO.NET с асинхронными операциями (например, BeginExecuteNonQuery/EndExecuteNonQuery). Они присутствуют только в очень немногих реализациях ADO.NET. (SqlClient, Devart Oracle).

Сказанное, если не установлено время, когда установлен CommandTimeOut, на мой взгляд это ошибка в провайдере.

0

Вы можете оформить LOCK TABLE с опцией NOWAIT? Это приведет к немедленному возврату элемента управления с ошибкой, если блокировка завершится с ошибкой. Например:

LOCK TABLE employees 
    IN EXCLUSIVE MODE 
    NOWAIT; 

Существует несколько способов блокировки стола. Here - раздел руководства разработчика по блокировке. This - это справочная страница SQL для команды LOCK TABLE.

Другим вариантом является использование инструкции SELECT .. FOR UPDATE NOWAIT для блокировки строк, которые вы будете обновлять. Оба варианта требуют дополнительных команд для Oracle, помимо вашего оператора обновления.

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