Rainbow Engine

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

C#

.NETで「SystemInvalidOperationException」例外(ZombieCheck、Rollback)の調査記録

投稿日:2021年5月29日 更新日:

<目次>

(1) .NETで「SystemInvalidOperationException」例外(ZombieCheck、Rollback)の調査記録
 (1-1) エラーメッセージ
 (1-2) 原因・対処(例)
 (1-3) 再現テスト

(1) .NETで「SystemInvalidOperationException」例外(ZombieCheck、Rollback)の調査記録

.NETでDB操作をした際に「SystemInvalidOperationException」が発生した際の調査備忘メモです。

(1-1) エラーメッセージ

(エラーメッセージ)

System.InvalidOperationException: This SqlTransaction has completed; it is no longer usable.
   at System.Data.SqlClient.SqlTransaction.ZombieCheck()
   at System.Data.SqlClient.SqlTransaction.Rollback()

 

目次にもどる

(1-2) 原因・対処(例)

あくまで一例ですが、Rollback()やCommit()の処理で発生していました。何かしらの原因で接続がclose()されてしまった場合に、そのクローズされた接続を使ってRollback()やCommit()を実行しようとするとエラーになっているようです。

目次にもどる

(1-3) 再現テスト

こちらのサイトを参考に再現を行ったのが以下プログラムですが、ポイントとなる点は次の通りです。

(再現STEP1)接続(con)をOpenした後、tryの一番最初でその接続をClose
con.Close()

 

(再現STEP2)クローズされた接続(con)を使ってSQL(INSERT文)を実行
cmd.Connection = con;
cmd.ExecuteNonQuery();

※ExecuteNonQueryはデータの返却がないINSERTやUPDATEの実行に使用します。

(再現STEP3)InvalidOperationException例外が発生し、それをキャッチ
catch (InvalidOperationException iex)

 

(再現STEP4)catchした中でRollbackするとClose済の接続のため例外が起きる
trn.Rollback();

 

(Exception再現プログラム)

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace SQLExceptionTest
{
  class Program
  {
    static void Main(string[] args)
    {

      string dataSource, initCatalog, userId, passWord, connectionString;
      dataSource = "[ホスト名]";
      initCatalog = "[データベース名]";
      userId = "[ユーザID]";
      passWord = "[パスワード]";
      connectionString = @"Data Source=" + dataSource + ";Initial Catalog=" + initCatalog + ";User ID=" + userId + ";Password=" + passWord;
      //SELECT文を作成
      string query_i = "INSERT INTO dbo.ACCESS_COUNTER VALUES (6,'GOLD',10);";

      SqlConnection con = new SqlConnection(connectionString);
      SqlTransaction trn;
      //接続を確立
      con.Open();
      trn = con.BeginTransaction();
      try
      {
        //接続を敢えてクローズ
        con.Close();
        SqlCommand cmd = new SqlCommand(query_i);
        cmd.Connection = con;
        cmd.ExecuteNonQuery();
      }catch (InvalidOperationException iex)
      {
        Console.WriteLine("# InvalidOperationException #");
        Console.WriteLine(iex.Message);
        //# ↓ここでクローズされた接続(con)を使ってRollbackしようとしたためエラーになっている
        trn.Rollback();
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
    }
  }
}

(図121)

目次にもどる

Adsense審査用広告コード


Adsense審査用広告コード


-C#

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

C#でフォルダ内のファイルの一覧を取得する方法

<目次> (1) C#でフォルダ内のファイルの一覧を取得する方法  (1-1) 方法①構文  (1-2) 方法①サンプルプログラム  (1-3) 方法②構文  (1-4) 方法②サンプルプログラム ( …

C#で「CS0518: 定義済みの型 ‘System.Range’は定義、またはインポートされていません」エラーが出た時の原因と対処

  <目次> (1) C#で「CS0518: 定義済みの型 ‘System.Range’は定義、またはインポートされていません」エラーが出た時の原因と対処  (1-1 …

ASP.NET MVCにおけるSessionオブジェクトについて

<目次> (1) ASP.NET MVCにおけるSessionオブジェクトについて  (1-1) Session(セッション)とは?   (1-1-1) セッションの開始と終了  (1-2) Sess …

ASP.NETのMVCとは?入門者向けの概要説明やHelloWorld

<目次> (1) ASP.NETのMVCとは?入門者向けの概要説明やHelloWorld  (1-1) ASP.NET MVC5とは?  (1-2) MVCのアーキテクチャ概要  (1-3) ASP. …

BundleConfig.csが読み込まれない場合の確認ポイントについて(ASP.NET)

  <目次> (1) BundleConfig.csが読み込まれない場合の確認ポイントについて(ASP.NET)  (1-1) 前提条件  (1-2) 確認ポイント   (確認①)Bundl …

  • English (United States)
  • 日本語
Top