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#で型をStringからintに変更する方法~TryParseメソッドによる型変換~

<目次> (1) C#で型をStringからintに変更する方法  (1-1) 構文  (1-2) サンプルプログラム  (1-3) プログラム補足「'{0}’や'{1}’」に …

no image

C#でコンソールにパスワード入力する際のマスキング処理の実装例のご紹介

  <目次> (1) C#でコンソールにパスワード入力する際のマスキング処理の実装例のご紹介  (1-1) 構文  (1-2) サンプルプログラム (1) C#でコンソールにパスワード入力す …

Xamarin.Formsのプロジェクトの構成について~各ファイルの役割や概要について~

<目次> (1) Xamarin.Formsのプロジェクトの構成について  (1-1) プロジェクト構造の概要  (1-2) プロジェクトの初期ファイルの一覧 (1) Xamarin.Formsのプロ …

SOAP通信のサンプルをご紹介(ASP.NET Web Service=ASMXを使ったHelloWorld)

  <目次> (1) SOAP通信のサンプルをご紹介(ASP.NET Web Service=ASMXを使ったHelloWorld)  (1-1) SOAP通信とは?  (1-2) SOAP …

C#のDB接続時のエラー(provider: Named Pipes Provider, error: 40 – Could not open a connection to SQL Server)

<目次> (1) 記事の目的  (1-1) エラー概要  (1-2) エラー原因  (1-3) エラー対策   (1-3-1) SQLServer:リモート接続を有効化   (1-3-2) SQLSe …

  • English (United States)
  • 日本語
Top