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行ずつ読み込み処理を行うサンプルプログラム

<目次> (1) C#でファイルを読み込み処理を行うサンプルプログラム  (1-1) 構文  (1-2) サンプルプログラム  (1-3) サンプルプログラムの補足 (1) C#でファイルを読み込み処 …

ASP.NETでビュー(View)に複数のモデル(Model)を連携する方法

  <目次> (1) ASP.NETでビュー(View)に複数のモデル(Model)を連携する方法  (1-1) やりたい事の整理  (1-2) ViewModelを使った複数モデルの連携 …

C#で配列に特定の値があるか?をチェックする方法を2つご紹介~ContainsとLINQ~

<目次> (1) C#で配列に特定の値があるか?をチェックする方法  (1-1) 方法①:ListクラスのContainsメソッドを使う方法   (1-1-1) 構文   (1-1-2) サンプルプロ …

C#のIComparableの実装方法+IComparerとの違いについて

<目次> (1) C#のIComparableの実装方法+IComparerとの違いについて  (1-1) IComparableの概要とIComparableとの違い  (1-2) STEP0:比較 …

C#のlockとは?意味や使い方とサンプルプログラムをご紹介

  <目次> (1) C#のlockとは?意味や使い方とサンプルプログラムをご紹介  (1-1) 概要  (1-2) 構文  (1-3) サンプルプログラム  (1-4) lockステートメ …

  • English (United States)
  • 日本語
Top