60

私はこれに約1日半取り組んでおり、Web上の多数のブログやヘルプ記事を検索しました。このエラーに関連するSOに関するいくつかの質問を見つけましたが、それらが私の状況に完全に当てはまるとは思いませんでした(または、残念ながら、:Pを実装するのに十分に理解できなかった場合もあります)。私はこれを助けのために十分に説明できるかどうかわかりません...しかしここに行きます:

リソースを追跡するための.NETアプリがあります。リソースをタイムトラッキングシステムと課金システムにコピーするためのエクスポート機能があります。これは、時間および請求データベースにリンクするストアドプロシージャにアクセスします。

最近、課金システムデータベースを新しいサーバー(元のサーバー:Server 2003 SP2、SQL 2005、新しいサーバー:Server 2008 R2、SQL 2008 R2)に移動しました。2008データベースを指すリンクサーバーをセットアップしました。2008サーバーを指すようにストアドプロシージャを更新したところ、MSDTCとRPC(http://www.safnet.com/writing/tech/archives/2007/06/server_myserver.html)に関するエラーが発生しました。リンクサーバーで「rpc/rpcout」を有効にし、ネットワークアクセスを許可するようにMSDTCを設定しました(http://www.sqlwebpedia.com/content/msdtc-troubleshootingのようなもの)。

エクスポート機能を実行しようとすると、「このSqlTransactionは完了しました。使用できなくなりました」という、上記の情報が表示されます。私には奇妙に思えますが、(SSMSから)ストアドプロシージャを実行すると、正常に完了したと表示されます。

誰かがこれを見たことがありますか?構成で何かを見逃しましたか?同じページを何度も繰り返しますが、MSDTCを変更した後、再起動しなかったことがわかりました(http://social.msdn.microsoft.com/forums/en-US/adodotnetdataprovidersに記載されています)。 / thread / 7172223f-acbe-4472-8cdf-feec80fd2e64 /)。

役立つ場合は、ストアドプロシージャの一部またはすべてを投稿できます...お知らせください。

4

10 に答える 10

51

このエラーメッセージは「ゾンビトランザクション」が原因だと思います。

トランザクトンが2回コミットされている(または2回ロールバックされている、またはロールバックされてコミットされているなど)可能性のある領域を探します。SPがすでにトランザクションをコミットした後、.Netコードはトランザクションをコミットしますか?.Netコードは、エラーが発生したときにロールバックしてから、catch(またはfinally)句で再度ロールバックを試みますか?

古いサーバーでエラー状態が発生しなかった可能性があるため、障害のある「ダブルロールバック」コードが発生しなかった可能性があります。新しいサーバーで構成エラーが発生し、例外処理によって障害のあるコードがヒットする状況が発生している可能性があります。

エラーコードをデバッグできますか?スタックトレースはありますか?

于 2011-06-15T14:13:28.033 に答える
9

新しい接続マネージャーでリファクタリングした後、最近これが発生しました。新しいルーチンがトランザクションを受け入れたため、バッチの一部として実行できました。問題は、ブロックの使用にありました。

public IEnumerable<T> Query<T>(IDbTransaction transaction, string command, dynamic param = null)
{
  using (transaction.Connection)
  {
    using (transaction)
    {
      return transaction.Connection.Query<T>(command, new DynamicParameters(param), transaction, commandType: CommandType.StoredProcedure);
    }
  }
}

外部の使用が基盤となる接続を閉じているように見えるため、トランザクションをコミットまたはロールバックしようとすると、メッセージがスローされます。"This SqlTransaction has completed; it is no longer usable."

カバーテストを追加して使用を削除すると、問題は解決しました。

public IEnumerable<T> Query<T>(IDbTransaction transaction, string command, dynamic param = null)
{
  return transaction.Connection.Query<T>(command, new DynamicParameters(param), transaction, commandType: CommandType.StoredProcedure);
}

トランザクションのコンテキスト内で接続を閉じる可能性のあるものがないか確認します。

于 2014-07-13T07:58:51.710 に答える
9

まったく同じ問題があり、正しい解決策を見つけることができませんでした。これが誰かに役立つことを願っています。

EFCoreを備えた.NETCore3.1WebApiがあります。同時に複数の呼び出しを受信すると、アプリケーションはデータベースへの変更を同時に追加および保存しようとしました。

私の場合、問題は、データが保存されるテーブルに主キーが設定されていないことでした。

モデル内のIDが主キーであると想定されていたアプリケーションから移行を実行したときに、どういうわけかEFCoreが失敗しました。

SQLプロファイラーを開いて、すべてのトランザクションが(アプリケーションから)データベースに正常に送信されたが、新しい行が1つだけ作成されたことを確認して、問題を見つけました。プロファイラーはまた、ある種のデッドロックが発生していることを示しましたが、プロファイラーのトレースログにはそれ以上のことはわかりませんでした。さらに調べてみると、「Id」列に主キー識別子がないことに気づきました。

アプリケーションから得た例外は次のとおりです。

このSqlTransactionは完了しました。使用できなくなりました。

および/または

一時的な障害が原因である可能性が高い例外が発生しました。'UseSqlServer'呼び出しに'EnableRetryOnFailure()'を追加して、一時的なエラー回復力を有効にすることを検討してください。

于 2020-07-08T13:41:43.420 に答える
7

私も同じ問題を抱えてる。このエラーは、接続プーリングが原因で発生します。2人以上のユーザーがシステムにアクセスする場合、接続プーリングは接続と変換も再利用します。最初のユーザーがcommitourollbackを実行すると、トランザクションは使用できなくなります。

于 2015-08-21T14:28:09.760 に答える
5

私は最近、同様の状況に遭遇しました。VS IDEのバージョンでデバッグするには、デバッグから例外を開きます(Ctrl + D、E)-[スロー]列のすべてのチェックボックスをオンにして、アプリケーションをデバッグモードで実行します。テーブルの1つが新しいデータベースに正しくインポートされなかったため、内部SQL例外によって接続が切断され、このエラーが発生したことに気付きました。

ストーリーの要点は、以前に機能していたコードが新しいデータベースでこのエラーを返す場合、これはデータベーススキーマの欠落の問題である可能性があります。上記のデバッグのヒントで、

お役に立てば幸い、HydTechie

于 2013-05-15T14:18:36.943 に答える
4

また、.NETアプリからDBに対して実行された長時間実行プロセスを確認します。たとえば、ログに次のように表示される可能性のある、終了するのに十分な時間がないストアドプロシージャまたはクエリを呼び出している場合があります。

  • 実行タイムアウトが期限切れになりました。操作が完了する前にタイムアウト期間が経過したか、サーバーが応答していません。

    • このSqlTransactionは完了しました。使用できなくなりました。

コマンドタイムアウト設定を確認するトレース(プロファイラー)を実行して、DB側で何が起こっているかを確認してください...

于 2016-12-29T18:52:13.500 に答える
3

私の場合、問題は、トランザクションに含まれるクエリの1つが例外を発生させていたことであり、例外が「適切に」処理されたとしても、トランザクション全体をロールバックすることができました。

私の擬似コードは次のようなものでした:

var transaction = connection.BeginTransaction();
for(all the lines in a file)
{
     try{
         InsertLineInTable(); // INSERT statement might fail and throw an exception
     }
     catch {
         // notify the user about the error on line x and continue
     }
}

// Commit and Rollback will fail if one of the queries 
// in InsertLineInTable threw an exception
if(CheckTableForErrors())
{
    transaction.Commit();
}
else
{
    transaction.Rollback();
}
于 2015-02-09T17:04:38.287 に答える
1

ゾンビトランザクションを検出する方法は次のとおりです

SqlTransaction trans = connection.BeginTransaction();

//some db calls here

if (trans.Connection != null) //Detecting zombie transaction
{
  trans.Commit();
}

SqlTransactionクラスを逆コンパイルすると、次のように表示されます。

public SqlConnection Connection
{
  get
  {
    if (this.IsZombied)
      return (SqlConnection) null;
    return this._connection;
  }
}

接続が閉じられると、transOPがゾンビになるため、できなくなりCommitます。私の場合、接続がブロックCommit()内にあるのに、ブロック内にあるためです。この配置により、接続が破棄され、ガベージコレクションが発生します。解決策は、代わりにブロック内に配置することでした。finallytryCommittry

于 2016-02-10T21:42:32.327 に答える
0

私の場合、同じtry-catchブロックで、トランザクションをコミットした後に実行する必要のあるコードがいくつかあります。コードの1つがエラーをスローし、トランザクションのロールバックを含むキャッチブロックにエラーを渡したブロックを試行します。同様のエラーが表示されます。たとえば、以下のコード構造を見てください。

SqlTransaction trans = null;

try{
 trans = Con.BeginTransaction();
// your codes

  trans.Commit();
//your codes having errors

}
catch(Exception ex)
{
     trans.Rollback(); //transaction roll back
    // error message
}

finally
{ 
    // connection close
}

それが誰かを助けることを願っています:)

于 2019-03-06T03:06:04.683 に答える
0

その価値については、以前は機能していたコードでこれに遭遇しました。デバッグテストのトリガーにSELECTステートメントを追加しましたが、削除するのを忘れていました。Entity Framework / MVCは、他のものが「グリッド」に出力されるとうまく機能しません。不正なクエリがないか確認して削除してください。

于 2021-02-24T14:42:37.637 に答える