QA@IT
«質問へ戻る

139
本文
 
 【疑問2】
 >try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
+
 とありますが、更新部分で複数のテーブルに対して処理を行う場合は
 UsingでCMD1、CMD2、CMD3等と宣言し、下記のように記述するのはいけないのでしょうか?
 やはりCMD1、CMD2、CMD3それぞれにTry-Catchを記述するものなのでしょうか?

VB.NET+ODP.NETでトランザクション実行時のエラーメッセージ

Windows7 Professional
VB2008+Oracle11gR2(サーバー・クライアントともに32bit)

お世話になります。

フォームアプリケーションから複数のデータ更新を行う際にトランザクションを
設定しているのですが、エラーをCatchした際のメッセージが

「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」

というものになり、実際に発生したエラーが何であったのかを知ることが出来ません。

Public Sub TEST

Dim Tran as Oracletransaction=Nothing
Try
 Using CON As New OracleConnection(接続文字列)
  CON.Open()
  Tran=CON.BeginTransaction
   Using CMD As New OracleCommand("", CON)

 更新処理
  Tran.Commit

   End Using
 End Using

Catch ex As OracleException
      Tran.Rollback
      MessageBox.Show(ex.ToString)
Catch ex As Exception
      Tran.Rollback
      MessageBox.Show(ex.ToString)
End Sub

ここで何らかのエラーが発生したときのメッセージが
「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」ですと
原因究明が出来ませんので、都度トランザクションに関する部分をコメントアウトして
エラーを再現させています。

どのように記述すればトランザクションをかけたまま元のエラーを知ることが出来るのでしょうか。

2014.03.11 編集しました

以下、SurferOnWww様がご提示下さったリンク先の引用です。

① try-catch ブロックは、基本的に、例外を業務エラーなどに変換したい場合に使う。
try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
一般例外(Exception クラス)ではなく、特定の例外(SqlException など)のみを捕捉する。
catch した後には、必ず後処理(業務エラーへの変換など)を記述する。
② try-finally ブロックは、基本的に、リソースを確実に解放したい場合に使う。
try-finally ブロックは、アプリケーション全体を囲む。
一般例外(Exception クラス)すべてに対して有効になるように記述する。
catch ブロックは書かない。

これを受けてこのように書きなおしてみました。

Public Sub TEST

 Using CON As New OracleConnection(接続文字列)
   Using CMD As New OracleCommand("", CON)

 更新処理

   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD.Transaction = TRAN
   Try
     CMD.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try

   Tran.Commit

   End Using
 End Using

この場合ですとCatchのなかでRollbackが実行されることを確認しました。

【疑問1】
この理解で正しいでしょうか?

【疑問2】

try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。

とありますが、更新部分で複数のテーブルに対して処理を行う場合は
UsingでCMD1、CMD2、CMD3等と宣言し、下記のように記述するのはいけないのでしょうか?
やはりCMD1、CMD2、CMD3それぞれにTry-Catchを記述するものなのでしょうか?

   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD1.Transaction = TRAN
   CMD2.Transaction = TRAN
   CMD3.Transaction = TRAN
   Try
     CMD1.ExecuteNonQuery()
     CMD2.ExecuteNonQuery()
     CMD3.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try

【疑問3】
DB接続時以外の一般エラー
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Sub
これをどこへ書けば正しいのか分からなくなってしまいました。

一般例外(Exception クラス)すべてに対して有効になるように記述する。

とあるもののtry-finally ブロックは

catch ブロックは書かない。

ともあるからです。

また、Using~End Usingで記述するとFainallyは不要だと理解していたのですが、
これも誤った解釈だったのということでしょうか。

Windows7 Professional
VB2008+Oracle11gR2(サーバー・クライアントともに32bit)

お世話になります。

フォームアプリケーションから複数のデータ更新を行う際にトランザクションを
設定しているのですが、エラーをCatchした際のメッセージが

「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」

というものになり、実際に発生したエラーが何であったのかを知ることが出来ません。

```
Public Sub TEST

Dim Tran as Oracletransaction=Nothing
Try
 Using CON As New OracleConnection(接続文字列)
  CON.Open()
  Tran=CON.BeginTransaction
   Using CMD As New OracleCommand("", CON)

 更新処理
  Tran.Commit

   End Using
 End Using

Catch ex As OracleException
      Tran.Rollback
      MessageBox.Show(ex.ToString)
Catch ex As Exception
      Tran.Rollback
      MessageBox.Show(ex.ToString)
End Sub
```

ここで何らかのエラーが発生したときのメッセージが
「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」ですと
原因究明が出来ませんので、都度トランザクションに関する部分をコメントアウトして
エラーを再現させています。

どのように記述すればトランザクションをかけたまま元のエラーを知ることが出来るのでしょうか。





2014.03.11 編集しました

以下、SurferOnWww様がご提示下さったリンク先の引用です。

>① try-catch ブロックは、基本的に、例外を業務エラーなどに変換したい場合に使う。
>try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
>一般例外(Exception クラス)ではなく、特定の例外(SqlException など)のみを捕捉する。
>catch した後には、必ず後処理(業務エラーへの変換など)を記述する。
>② try-finally ブロックは、基本的に、リソースを確実に解放したい場合に使う。
>try-finally ブロックは、アプリケーション全体を囲む。
>一般例外(Exception クラス)すべてに対して有効になるように記述する。
>catch ブロックは書かない。

これを受けてこのように書きなおしてみました。
```
Public Sub TEST

 Using CON As New OracleConnection(接続文字列)
   Using CMD As New OracleCommand("", CON)

 更新処理

   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD.Transaction = TRAN
   Try
     CMD.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try

   Tran.Commit

   End Using
 End Using
```

この場合ですとCatchのなかでRollbackが実行されることを確認しました。

【疑問1】
この理解で正しいでしょうか?

【疑問2】
>try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。

とありますが、更新部分で複数のテーブルに対して処理を行う場合は
UsingでCMD1、CMD2、CMD3等と宣言し、下記のように記述するのはいけないのでしょうか?
やはりCMD1、CMD2、CMD3それぞれにTry-Catchを記述するものなのでしょうか?
```
   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD1.Transaction = TRAN
   CMD2.Transaction = TRAN
   CMD3.Transaction = TRAN
   Try
     CMD1.ExecuteNonQuery()
     CMD2.ExecuteNonQuery()
     CMD3.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try
```

【疑問3】
DB接続時以外の一般エラー
Catch ex As Exception
      MessageBox.Show(ex.ToString)
End Sub
これをどこへ書けば正しいのか分からなくなってしまいました。

>一般例外(Exception クラス)すべてに対して有効になるように記述する。

とあるもののtry-finally ブロックは

>catch ブロックは書かない。

ともあるからです。

また、Using~End Usingで記述するとFainallyは不要だと理解していたのですが、
これも誤った解釈だったのということでしょうか。

139
本文
      End If
    End Try
 ```
-しかし、DB接続時以外の一般エラー
+
+【疑問3】
+DB接続時以外の一般エラー
 Catch ex As Exception
       MessageBox.Show(ex.ToString)
 End Sub

VB.NET+ODP.NETでトランザクション実行時のエラーメッセージ

Windows7 Professional
VB2008+Oracle11gR2(サーバー・クライアントともに32bit)

お世話になります。

フォームアプリケーションから複数のデータ更新を行う際にトランザクションを
設定しているのですが、エラーをCatchした際のメッセージが

「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」

というものになり、実際に発生したエラーが何であったのかを知ることが出来ません。

Public Sub TEST

Dim Tran as Oracletransaction=Nothing
Try
 Using CON As New OracleConnection(接続文字列)
  CON.Open()
  Tran=CON.BeginTransaction
   Using CMD As New OracleCommand("", CON)

 更新処理
  Tran.Commit

   End Using
 End Using

Catch ex As OracleException
      Tran.Rollback
      MessageBox.Show(ex.ToString)
Catch ex As Exception
      Tran.Rollback
      MessageBox.Show(ex.ToString)
End Sub

ここで何らかのエラーが発生したときのメッセージが
「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」ですと
原因究明が出来ませんので、都度トランザクションに関する部分をコメントアウトして
エラーを再現させています。

どのように記述すればトランザクションをかけたまま元のエラーを知ることが出来るのでしょうか。

2014.03.11 編集しました

以下、SurferOnWww様がご提示下さったリンク先の引用です。

① try-catch ブロックは、基本的に、例外を業務エラーなどに変換したい場合に使う。
try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
一般例外(Exception クラス)ではなく、特定の例外(SqlException など)のみを捕捉する。
catch した後には、必ず後処理(業務エラーへの変換など)を記述する。
② try-finally ブロックは、基本的に、リソースを確実に解放したい場合に使う。
try-finally ブロックは、アプリケーション全体を囲む。
一般例外(Exception クラス)すべてに対して有効になるように記述する。
catch ブロックは書かない。

これを受けてこのように書きなおしてみました。

Public Sub TEST

 Using CON As New OracleConnection(接続文字列)
   Using CMD As New OracleCommand("", CON)

 更新処理

   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD.Transaction = TRAN
   Try
     CMD.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try

   Tran.Commit

   End Using
 End Using

この場合ですとCatchのなかでRollbackが実行されることを確認しました。

【疑問1】
この理解で正しいでしょうか?

【疑問2】

try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
とありますが、更新部分で複数のテーブルに対して処理を行う場合は
UsingでCMD1、CMD2、CMD3等と宣言し、下記のように記述するのはいけないのでしょうか?
やはりCMD1、CMD2、CMD3それぞれにTry-Catchを記述するものなのでしょうか?

   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD1.Transaction = TRAN
   CMD2.Transaction = TRAN
   CMD3.Transaction = TRAN
   Try
     CMD1.ExecuteNonQuery()
     CMD2.ExecuteNonQuery()
     CMD3.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try

【疑問3】
DB接続時以外の一般エラー
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Sub
これをどこへ書けば正しいのか分からなくなってしまいました。

一般例外(Exception クラス)すべてに対して有効になるように記述する。

とあるもののtry-finally ブロックは

catch ブロックは書かない。

ともあるからです。

また、Using~End Usingで記述するとFainallyは不要だと理解していたのですが、
これも誤った解釈だったのということでしょうか。

Windows7 Professional
VB2008+Oracle11gR2(サーバー・クライアントともに32bit)

お世話になります。

フォームアプリケーションから複数のデータ更新を行う際にトランザクションを
設定しているのですが、エラーをCatchした際のメッセージが

「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」

というものになり、実際に発生したエラーが何であったのかを知ることが出来ません。

```
Public Sub TEST

Dim Tran as Oracletransaction=Nothing
Try
 Using CON As New OracleConnection(接続文字列)
  CON.Open()
  Tran=CON.BeginTransaction
   Using CMD As New OracleCommand("", CON)

 更新処理
  Tran.Commit

   End Using
 End Using

Catch ex As OracleException
      Tran.Rollback
      MessageBox.Show(ex.ToString)
Catch ex As Exception
      Tran.Rollback
      MessageBox.Show(ex.ToString)
End Sub
```

ここで何らかのエラーが発生したときのメッセージが
「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」ですと
原因究明が出来ませんので、都度トランザクションに関する部分をコメントアウトして
エラーを再現させています。

どのように記述すればトランザクションをかけたまま元のエラーを知ることが出来るのでしょうか。





2014.03.11 編集しました

以下、SurferOnWww様がご提示下さったリンク先の引用です。

>① try-catch ブロックは、基本的に、例外を業務エラーなどに変換したい場合に使う。
>try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
>一般例外(Exception クラス)ではなく、特定の例外(SqlException など)のみを捕捉する。
>catch した後には、必ず後処理(業務エラーへの変換など)を記述する。
>② try-finally ブロックは、基本的に、リソースを確実に解放したい場合に使う。
>try-finally ブロックは、アプリケーション全体を囲む。
>一般例外(Exception クラス)すべてに対して有効になるように記述する。
>catch ブロックは書かない。

これを受けてこのように書きなおしてみました。
```
Public Sub TEST

 Using CON As New OracleConnection(接続文字列)
   Using CMD As New OracleCommand("", CON)

 更新処理

   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD.Transaction = TRAN
   Try
     CMD.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try

   Tran.Commit

   End Using
 End Using
```

この場合ですとCatchのなかでRollbackが実行されることを確認しました。

【疑問1】
この理解で正しいでしょうか?

【疑問2】
>try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
とありますが、更新部分で複数のテーブルに対して処理を行う場合は
UsingでCMD1、CMD2、CMD3等と宣言し、下記のように記述するのはいけないのでしょうか?
やはりCMD1、CMD2、CMD3それぞれにTry-Catchを記述するものなのでしょうか?
```
   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD1.Transaction = TRAN
   CMD2.Transaction = TRAN
   CMD3.Transaction = TRAN
   Try
     CMD1.ExecuteNonQuery()
     CMD2.ExecuteNonQuery()
     CMD3.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try
```

【疑問3】
DB接続時以外の一般エラー
Catch ex As Exception
      MessageBox.Show(ex.ToString)
End Sub
これをどこへ書けば正しいのか分からなくなってしまいました。

>一般例外(Exception クラス)すべてに対して有効になるように記述する。

とあるもののtry-finally ブロックは

>catch ブロックは書かない。

ともあるからです。

また、Using~End Usingで記述するとFainallyは不要だと理解していたのですが、
これも誤った解釈だったのということでしょうか。

139
本文
 エラーを再現させています。
 
 どのように記述すればトランザクションをかけたまま元のエラーを知ることが出来るのでしょうか。
+
+
+
+
+
+2014.03.11 編集しました
+
+以下、SurferOnWww様がご提示下さったリンク先の引用です。
+
+>① try-catch ブロックは、基本的に、例外を業務エラーなどに変換したい場合に使う。
+>try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
+>一般例外(Exception クラス)ではなく、特定の例外(SqlException など)のみを捕捉する。
+>catch した後には、必ず後処理(業務エラーへの変換など)を記述する。
+>② try-finally ブロックは、基本的に、リソースを確実に解放したい場合に使う。
+>try-finally ブロックは、アプリケーション全体を囲む。
+>一般例外(Exception クラス)すべてに対して有効になるように記述する。
+>catch ブロックは書かない。
+
+これを受けてこのように書きなおしてみました。
+```
+Public Sub TEST
+
+ Using CON As New OracleConnection(接続文字列)
+   Using CMD As New OracleCommand("", CON)
+
+ 更新処理
+
+   CON.Open
+   Dim TRAN As OracleTransaction = Nothing
+   TRAN = CON.BeginTransaction
+   CMD.Transaction = TRAN
+   Try
+     CMD.ExecuteNonQuery()
+   Catch ex As OracleException
+     MessageBox.Show(ex.ToString)
+     If Not TRAN Is Nothing Then
+        TRAN.Rollback()
+     End If
+   End Try
+
+   Tran.Commit
+
+   End Using
+ End Using
+```
+
+この場合ですとCatchのなかでRollbackが実行されることを確認しました。
+
+【疑問1】
+この理解で正しいでしょうか?
+
+【疑問2】
+>try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
+とありますが、更新部分で複数のテーブルに対して処理を行う場合は
+UsingでCMD1、CMD2、CMD3等と宣言し、下記のように記述するのはいけないのでしょうか?
+やはりCMD1、CMD2、CMD3それぞれにTry-Catchを記述するものなのでしょうか?
+```
+   CON.Open
+   Dim TRAN As OracleTransaction = Nothing
+   TRAN = CON.BeginTransaction
+   CMD1.Transaction = TRAN
+   CMD2.Transaction = TRAN
+   CMD3.Transaction = TRAN
+   Try
+     CMD1.ExecuteNonQuery()
+     CMD2.ExecuteNonQuery()
+     CMD3.ExecuteNonQuery()
+   Catch ex As OracleException
+     MessageBox.Show(ex.ToString)
+     If Not TRAN Is Nothing Then
+        TRAN.Rollback()
+     End If
+   End Try
+```
+しかし、DB接続時以外の一般エラー
+Catch ex As Exception
+      MessageBox.Show(ex.ToString)
+End Sub
+これをどこへ書けば正しいのか分からなくなってしまいました。
+
+>一般例外(Exception クラス)すべてに対して有効になるように記述する。
+
+とあるもののtry-finally ブロックは
+
+>catch ブロックは書かない。
+
+ともあるからです。
+
+また、Using~End Usingで記述するとFainallyは不要だと理解していたのですが、
+これも誤った解釈だったのということでしょうか。

VB.NET+ODP.NETでトランザクション実行時のエラーメッセージ

Windows7 Professional
VB2008+Oracle11gR2(サーバー・クライアントともに32bit)

お世話になります。

フォームアプリケーションから複数のデータ更新を行う際にトランザクションを
設定しているのですが、エラーをCatchした際のメッセージが

「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」

というものになり、実際に発生したエラーが何であったのかを知ることが出来ません。

Public Sub TEST

Dim Tran as Oracletransaction=Nothing
Try
 Using CON As New OracleConnection(接続文字列)
  CON.Open()
  Tran=CON.BeginTransaction
   Using CMD As New OracleCommand("", CON)

 更新処理
  Tran.Commit

   End Using
 End Using

Catch ex As OracleException
      Tran.Rollback
      MessageBox.Show(ex.ToString)
Catch ex As Exception
      Tran.Rollback
      MessageBox.Show(ex.ToString)
End Sub

ここで何らかのエラーが発生したときのメッセージが
「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」ですと
原因究明が出来ませんので、都度トランザクションに関する部分をコメントアウトして
エラーを再現させています。

どのように記述すればトランザクションをかけたまま元のエラーを知ることが出来るのでしょうか。

2014.03.11 編集しました

以下、SurferOnWww様がご提示下さったリンク先の引用です。

① try-catch ブロックは、基本的に、例外を業務エラーなどに変換したい場合に使う。
try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
一般例外(Exception クラス)ではなく、特定の例外(SqlException など)のみを捕捉する。
catch した後には、必ず後処理(業務エラーへの変換など)を記述する。
② try-finally ブロックは、基本的に、リソースを確実に解放したい場合に使う。
try-finally ブロックは、アプリケーション全体を囲む。
一般例外(Exception クラス)すべてに対して有効になるように記述する。
catch ブロックは書かない。

これを受けてこのように書きなおしてみました。

Public Sub TEST

 Using CON As New OracleConnection(接続文字列)
   Using CMD As New OracleCommand("", CON)

 更新処理

   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD.Transaction = TRAN
   Try
     CMD.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try

   Tran.Commit

   End Using
 End Using

この場合ですとCatchのなかでRollbackが実行されることを確認しました。

【疑問1】
この理解で正しいでしょうか?

【疑問2】

try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
とありますが、更新部分で複数のテーブルに対して処理を行う場合は
UsingでCMD1、CMD2、CMD3等と宣言し、下記のように記述するのはいけないのでしょうか?
やはりCMD1、CMD2、CMD3それぞれにTry-Catchを記述するものなのでしょうか?

   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD1.Transaction = TRAN
   CMD2.Transaction = TRAN
   CMD3.Transaction = TRAN
   Try
     CMD1.ExecuteNonQuery()
     CMD2.ExecuteNonQuery()
     CMD3.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try

しかし、DB接続時以外の一般エラー
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Sub
これをどこへ書けば正しいのか分からなくなってしまいました。

一般例外(Exception クラス)すべてに対して有効になるように記述する。

とあるもののtry-finally ブロックは

catch ブロックは書かない。

ともあるからです。

また、Using~End Usingで記述するとFainallyは不要だと理解していたのですが、
これも誤った解釈だったのということでしょうか。

Windows7 Professional
VB2008+Oracle11gR2(サーバー・クライアントともに32bit)

お世話になります。

フォームアプリケーションから複数のデータ更新を行う際にトランザクションを
設定しているのですが、エラーをCatchした際のメッセージが

「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」

というものになり、実際に発生したエラーが何であったのかを知ることが出来ません。

```
Public Sub TEST

Dim Tran as Oracletransaction=Nothing
Try
 Using CON As New OracleConnection(接続文字列)
  CON.Open()
  Tran=CON.BeginTransaction
   Using CMD As New OracleCommand("", CON)

 更新処理
  Tran.Commit

   End Using
 End Using

Catch ex As OracleException
      Tran.Rollback
      MessageBox.Show(ex.ToString)
Catch ex As Exception
      Tran.Rollback
      MessageBox.Show(ex.ToString)
End Sub
```

ここで何らかのエラーが発生したときのメッセージが
「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」ですと
原因究明が出来ませんので、都度トランザクションに関する部分をコメントアウトして
エラーを再現させています。

どのように記述すればトランザクションをかけたまま元のエラーを知ることが出来るのでしょうか。





2014.03.11 編集しました

以下、SurferOnWww様がご提示下さったリンク先の引用です。

>① try-catch ブロックは、基本的に、例外を業務エラーなどに変換したい場合に使う。
>try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
>一般例外(Exception クラス)ではなく、特定の例外(SqlException など)のみを捕捉する。
>catch した後には、必ず後処理(業務エラーへの変換など)を記述する。
>② try-finally ブロックは、基本的に、リソースを確実に解放したい場合に使う。
>try-finally ブロックは、アプリケーション全体を囲む。
>一般例外(Exception クラス)すべてに対して有効になるように記述する。
>catch ブロックは書かない。

これを受けてこのように書きなおしてみました。
```
Public Sub TEST

 Using CON As New OracleConnection(接続文字列)
   Using CMD As New OracleCommand("", CON)

 更新処理

   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD.Transaction = TRAN
   Try
     CMD.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try

   Tran.Commit

   End Using
 End Using
```

この場合ですとCatchのなかでRollbackが実行されることを確認しました。

【疑問1】
この理解で正しいでしょうか?

【疑問2】
>try-catch ブロックは、例外が発生しうる『1 行』のみを囲む。
とありますが、更新部分で複数のテーブルに対して処理を行う場合は
UsingでCMD1、CMD2、CMD3等と宣言し、下記のように記述するのはいけないのでしょうか?
やはりCMD1、CMD2、CMD3それぞれにTry-Catchを記述するものなのでしょうか?
```
   CON.Open
   Dim TRAN As OracleTransaction = Nothing
   TRAN = CON.BeginTransaction
   CMD1.Transaction = TRAN
   CMD2.Transaction = TRAN
   CMD3.Transaction = TRAN
   Try
     CMD1.ExecuteNonQuery()
     CMD2.ExecuteNonQuery()
     CMD3.ExecuteNonQuery()
   Catch ex As OracleException
     MessageBox.Show(ex.ToString)
     If Not TRAN Is Nothing Then
        TRAN.Rollback()
     End If
   End Try
```
しかし、DB接続時以外の一般エラー
Catch ex As Exception
      MessageBox.Show(ex.ToString)
End Sub
これをどこへ書けば正しいのか分からなくなってしまいました。

>一般例外(Exception クラス)すべてに対して有効になるように記述する。

とあるもののtry-finally ブロックは

>catch ブロックは書かない。

ともあるからです。

また、Using~End Usingで記述するとFainallyは不要だと理解していたのですが、
これも誤った解釈だったのということでしょうか。

質問を投稿

VB.NET+ODP.NETでトランザクション実行時のエラーメッセージ

Windows7 Professional
VB2008+Oracle11gR2(サーバー・クライアントともに32bit)

お世話になります。

フォームアプリケーションから複数のデータ更新を行う際にトランザクションを
設定しているのですが、エラーをCatchした際のメッセージが

「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」

というものになり、実際に発生したエラーが何であったのかを知ることが出来ません。

Public Sub TEST

Dim Tran as Oracletransaction=Nothing
Try
 Using CON As New OracleConnection(接続文字列)
  CON.Open()
  Tran=CON.BeginTransaction
   Using CMD As New OracleCommand("", CON)

 更新処理
  Tran.Commit

   End Using
 End Using

Catch ex As OracleException
      Tran.Rollback
      MessageBox.Show(ex.ToString)
Catch ex As Exception
      Tran.Rollback
      MessageBox.Show(ex.ToString)
End Sub

ここで何らかのエラーが発生したときのメッセージが
「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」ですと
原因究明が出来ませんので、都度トランザクションに関する部分をコメントアウトして
エラーを再現させています。

どのように記述すればトランザクションをかけたまま元のエラーを知ることが出来るのでしょうか。

Windows7 Professional
VB2008+Oracle11gR2(サーバー・クライアントともに32bit)

お世話になります。

フォームアプリケーションから複数のデータ更新を行う際にトランザクションを
設定しているのですが、エラーをCatchした際のメッセージが

「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」

というものになり、実際に発生したエラーが何であったのかを知ることが出来ません。

```
Public Sub TEST

Dim Tran as Oracletransaction=Nothing
Try
 Using CON As New OracleConnection(接続文字列)
  CON.Open()
  Tran=CON.BeginTransaction
   Using CMD As New OracleCommand("", CON)

 更新処理
  Tran.Commit

   End Using
 End Using

Catch ex As OracleException
      Tran.Rollback
      MessageBox.Show(ex.ToString)
Catch ex As Exception
      Tran.Rollback
      MessageBox.Show(ex.ToString)
End Sub
```

ここで何らかのエラーが発生したときのメッセージが
「オブジェクトの現在の状態に問題があるため、操作は有効ではありません。」ですと
原因究明が出来ませんので、都度トランザクションに関する部分をコメントアウトして
エラーを再現させています。

どのように記述すればトランザクションをかけたまま元のエラーを知ることが出来るのでしょうか。