2009-07-23 20 views
7

Oracleのアップデートに問題があります。 ExecuteNonQueryの呼び出しは無期限にハングします。Oracleアップデートがハングアップ

コード:

using (OracleCommand cmd = new OracleCommand(dbData.SqlCommandStr, conn)) 
{ 
    foreach (string colName in dbData.Values.Keys) 
     cmd.Parameters.Add(colName, dbData.Values[colName]); 

    cmd.CommandTimeout = txTimeout; 
    int nRowsAffected = cmd.ExecuteNonQuery(); 
} 

CommandTimeoutのは5に設定され、パラメータは小さな整数値に設定されています。

クエリ:

UPDATE "BEN"."TABLE03" SET "COLUMN03"=:1,"COLUMN04"=:2 WHERE COLUMN05 > 0 

クエリがSQLPLUSからすぐに実行され、通常は自分のコードから高速で実行されますが、たまにではそれが永遠にハングします。

私はv $ locked_objectに関するクエリを実行しましたが、このテーブルを参照するレコードが1つありますが、それは完了していない更新だと思います。

私が知りたいことは2つあります。何が原因で更新がハングアップする可能性がありますか?

さらに重要なことは、ここで例外がスローされないのはなぜですか?コールが5秒待ってからタイムアウトすることを期待します。

+0

のOracleのバージョンは何?この問合せを実行するには、「select * from v $ version」を実行し、行1をコピーします。「Oracle Database 10gリリース10.2.0.4.0 - Production」のようになります。また、これは実際のテーブルか、トリガーの代わりに表示されますか?前/後トリガーはありますか? –

答えて

5

単純な更新がハングすると、別のセッションでブロックされていることがよくあります。 Oracleは、複数のトランザクションで行を更新することはできません。トランザクションが変更をコミットまたはロールバックするまで、更新または削除された行はロックされます。これは、同じ行を変更したい場合、他のセッションが待たなければならないことを意味します。

あなたが無期限にハングアップしたくない場合は、更新する前に[NO ...]を選択してください。

+0

+1、散発的なハングに対して特に当てはまります。 – DCookie

0

データベースがコミット/ロールバックを待機しているため、ローをロックするようです。私はあなたがあなたのセッションが(おそらくV $ SESSIONを見ることで、セッションのSIDを識別した後)V $ SESSION_WAITを問い合せて待機しているものイベント見ることができます

int nRowsAffected = cmd.ExecuteNonQuery(); 
cmd.Commit(); 
2

を追加することを示唆しています。イベントが "エンキュー"のようなものであれば、別のセッションで保持されているロックを待っています。

19

検索結果のページランクのためにこれが発生しています。

私の場合、SqlPlusでクエリを実行したためでしたが、コミットするのを忘れました。この場合、それはVincentが述べたとおりです。行は別のセッションでロックされていました。

SqlPlusアップデートをコミットすることで問題が解決されました。

+3

ありがとう、これは非常に役に立ちました。私は同じことをした... – stoj

+1

まさに私に起こったこと。 SQLPlusで 'rollback'を実行するとすぐに、それが返されました。 –

+0

ライフセーバー - 4年後! – jasonscript

0

私はこの問題に頻繁に遭遇しています。単にクエリを更新するだけではなく(特に "INSERT INTO ... SELECT FROM"クエリなど)これはOracle 9i上にあります。私は解決策を見つけた

ので、この関連のSOトピックを見つけることにしました:接続文字列で を、設定:接続文字列に

Pooling=False 

を。 フル、ワーキング接続文字列は次のようになります。

DATA SOURCE=k19.MYDOMAIN.com/plldb;PERSIST SECURITY INFO=True;Pooling=False;USER ID=IT;Password=SECRET 

警告:falseに設定すると、プールの新しい接続にそれが実行されたすべての時間を確保クエリが必要になります。非常に頻繁に実行される問合せでは、ODP.NETが信頼できる場合に比べてパフォーマンスが低下する可能性があります。しかし、問題を考えると、少し遅く走ることはぶら下げるよりはるかに良いです。

4

私はコミットされていないSqlコマンドに起因する同様の問題を抱えていました。プログラムの途中でプログラムがクラッシュしていると推測しています。

まず、オープンSQLPLUSや問題を解決するためにコミットします:ここで

は、私は私の問題を修正する方法です。

次に、例外が発生した場合はトランザクションをコミットするか、ロールバックするようにコードを変更します。それは問題が再び発生するのを防ぎます。

あなたはこのような何かにあなたのコードを変更することができます:

using (OracleTransaction transaction = conn.BeginTransaction()) 
{ 
    using (OracleCommand cmd = new OracleCommand(dbData.SqlCommandStr, conn)) 
    { 
     foreach (string colName in dbData.Values.Keys) 
      cmd.Parameters.Add(colName, dbData.Values[colName]); 

     cmd.CommandTimeout = txTimeout; 

     try 
     { 
      int nRowsAffected = cmd.ExecuteNonQuery(); 
      transaction.Commit(); 
     } 
     catch 
     { 
      transaction.Rollback(); 
     } 
    } 
} 
関連する問題