1

一般的なDbCommandを使用して更新を実行する場合、更新される行がロックされていると、無期限にハングします。

使用される基本的な接続は、DevartのOracleプロバイダーであるDevart.Data.Oracle.OracleConnectionです。

DbCommand.CommandTimeOutを設定してもまったく効果がなく、更新がタイムアウトすることはありません。

DbCommandはBeginExecuteNonQueryを実装していないため、非同期でDbConnection/DbCommandを使用する方法はないようです。

DevartのOracleCommandと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();
}
4

2 に答える 2

2

残念ながら、いいえ、非同期操作(BeginExecuteNonQuery / EndExecuteNonQueryなど)を持つインターフェイスまたは基本クラスはADO.NETにありません。これらは、ごく少数のADO.NETプロバイダーの実装にのみ存在します。(SqlClient、Devart Oracle)。

とはいえ、CommandTimeOutが設定されているときにタイムアウトにならない場合、私の意見では、それはプロバイダーのバグです。

于 2010-09-15T23:08:22.663 に答える
0

NOWAITオプションを使用してLOCKTABLEを発行できますか?これにより、ロックが失敗した場合にエラーが発生してすぐに制御が返されます。例えば:

LOCK TABLE employees
   IN EXCLUSIVE MODE 
   NOWAIT; 

テーブルをロックする方法はいくつかあります。これは、ロックに関する開発者向けガイドのセクションです。これは、LOCKTABLEコマンドのSQLリファレンスページです。

もう1つのオプションは、SELECT .. FOR UPDATE NOWAITステートメントを使用して、更新する行をロックすることです。どちらのオプションでも、updateステートメントに加えて追加のコマンドをOracleに発行する必要があります。

于 2009-05-11T17:58:00.513 に答える