0

3 つのタスクを実行する VB.Net デスクトップ アプリケーションがあります。最初にテーブル A、次にテーブル B にデータを挿入し、最後にあるディレクトリから別のディレクトリにファイルをコピーします。データベースの挿入にトランザクションを使用しています。3 つのステップのいずれかでエラーが発生した場合は、トランザクションをロールバックしたいと考えています。問題は、特定のシナリオが発生し、トランザクションをロールバックすると、次のエラーが発生することです。

 This OleDbTransaction has completed; it is no longer usable.

これは、両方のデータベースの挿入が成功したが、ファイルのコピーが失敗した場合に発生します。トランザクションの設定が間違っているのか、それとも何なのかわかりません。フィードバックがある場合は、お知らせください。ああ、私が使用しているデータベースは Oracle 10g です。以下は私のコードです:

Private Sub insertNew(ByVal doc As someObject)
   Dim conString As String
   conString = "Provider=MSDAORA.1;" _
                  & "User ID=" & My.Settings.User & ";" _
                  & "Password=" & My.Settings.Password & ";" _
                  & "Data Source=" & My.Settings.DatabaseName & ";" _
                  & "Persist Security Info=False"

   Dim insertString1 As String
   Dim insertString2 As String
   Dim transaction As OleDbTransaction  


   insertString1 = "INSERT INTO mySchema.myTable1(ID_DOC, ID_DOC_FORMAT) VALUES (?,?)"
   insertString2 = "INSERT INTO mySchema.myTable2(LOCATION_ID, PK_DOCUMENT) VALUES (?,?)"

   Dim conn As New OleDbConnection(conString)

   Try
      Dim nextValue As Integer
      'this function is a database call to get next sequence from database
      nextValue = readData()

      Using conn
        conn.Open()
        transaction = conn.BeginTransaction()

        Dim command1 As New OleDbCommand
        Dim command2 As New OleDbCommand

        Try
            With command1
               .Connection = conn
               .Transaction = transaction
               .CommandType = CommandType.Text
               .CommandText = insertString1
               .Parameters.Add("@IdDoc", OleDbType.VarChar).Value = doc.IdDoc
               .Parameters.Add("@IdDocFormat", OleDbType.VarChar).Value = doc.IdDocFormat
               .ExecuteNonQuery()
            End With
        Catch exCMD1 As Exception
             Throw New ApplicationException("unable to insert into table DM_DOCUMENTS (" & exCMD1.Message & ")")
        End Try

       Try
          With command2
           .Connection = conn
           .Transaction = transaction
           .CommandType = CommandType.Text
           .CommandText = insertString2
           .Parameters.Add("@IndPyramid", OleDbType.VarChar).Value = doc.IndPyramid
           .Parameters.Add("@LocationId", OleDbType.Integer).Value = doc.LocationId
           .ExecuteNonQuery()
          End With

        Catch exCMD2 As Exception
            Throw New ApplicationException("unable to insert into table DM_LOCATION_DOC_XREF (" & exCMD2.Message & ")")
        End Try

        If copyFiles(doc.IdDoc) = True Then
            transaction.Commit()
            'everything was a success, so commit
        Else
           'error copying file, so roll back.  
           '  If the error originates from here, it will throw to the next catch, and that is where I get the described error     
           Throw New ApplicationException("unable to copy to New Path")
        End If
    End Using
Catch ex As Exception
     If transaction IsNot Nothing Then
       'error occurs here if it came from trying to copy files code block
       transaction.Rollback()
     End If
     Throw
        Finally
            conn.Close()
            conn.Dispose()
        End Try

    End Sub
4

3 に答える 3

0

どうでも。これは、正しい Try Catch ステートメントの外側でトランザクションをロールバックしようとしていたためです。using ステートメントを終了すると、db が破棄され、エラーが発生します。try catch ステートメントをやり直したところ、正常に動作するようになりました。

于 2013-06-24T12:45:38.803 に答える
0

そのトランザクションに関連付けられた接続が null かどうかを確認すると、完了です。

トランザクションの接続オブジェクトが null でない場合にのみコミットまたはロールバックを適用する

例えば。

OleDBTransaction testTransaction = someOleDBConnection.BeginTransaction();

//すべてのトランザクション コード

if(testTransaction.Connection != null) testTransaction.Rollback() OR testTransaction.Commit() //要件に基づく

于 2014-03-05T17:50:16.437 に答える