.net Oracle 事务传递给 class byRef

.net Oracle Transaction passed to class byRef

我有一个通过 Ref 传递我的 oracle 连接和事务的过程。我所有的 inserts/deletes 似乎都工作正常。然而,其中一个更新似乎 运行 通过就好了,但是数据库中的数据没有更新。

我想知道我是否在提交之前不久就处理了 qry 对象,这就是原因。这是我第一次尝试使用 oracle 事务和我在网上找到的所有示例,似乎都是按方法执行的。在我提交之前,我需要确保它 运行 贯穿我的整个过程,否则我想回滚。

Using conn As New OracleConnection(myObject.ConnectionString)
    conn.Open()
    Dim myTrans As OracleTransaction
    myTrans = conn.BeginTransaction(IsolationLevel.ReadCommitted)

    Try
        If ClassName.Insert(conn, myTrans) THEN
        'Insert Happened
        End If

        If ClassName.Update(conn, myTrans) THEN

        End If

        If ClassName.Delete(conn, myTrans)  THEN

        End If

        MyTrans.Commit()
    Catch ex As Exception
        myTrans.Rollback()
    Finally

        'Close connection
        If conn.State <> ConnectionState.Closed AndAlso conn.State <> ConnectionState.Connecting Then
            conn.Close()
            conn.Dispose()
        End If

    End Try 
End Using

这是我的 class 更新函数的一个简单示例..

 Public Function Update(ByRef conn As OracleConnection, ByRef myTrans As OracleTransaction) As Boolean
    Dim result As Boolean = False
    Try
        Dim sql As String = ""
        sql = sql & "UPDATE TABLENAME "
        sql = sql & " SET"
        sql = sql & " xyz = :xyz"

        sql = sql & " WHERE id = :id"

        Using qry As New OracleCommand(sql, conn)
            qry.Transaction = myTrans
            qry.Parameters.Add("id", OracleDbType.Decimal, Me.ID, ParameterDirection.Input)
            qry.ExecuteNonQuery()
            result = True
            qry.Dispose()
        End Using

    Catch ex As Exception
    Finally
    End Try
    Return result

End Function

更新没有发生错误,数据库中的记录永远不会更新。

我不太了解 VB.net,但我知道 OracleCommand 构造函数希望将事务作为第三个参数。在 C# 中,它看起来像这样:

OracleCommand cmd = new OracleCommand(sql, connection, transaction);

由于交易是一个对象,我认为没有必要将其作为引用传递。在 C# 中,这无关紧要,除非您克隆对象,这对于数据库事务对象来说听起来是个非常糟糕的主意。

综上所述,如果您不使用该事务,那么它应该简单地绕过您打开的事务并基本上自动提交。

我认为您的代码正在抛出并捕获异常。你的 try/catch 只是掩盖了真正的问题,除非我错过了机会。您的 SQL 中有两个参数,但只绑定了一个。 :xyz 绑定在哪里?我怀疑这就是问题所在,但如果您希望使用该事务(以便您可以在最后提交),请确保将其包含在您的 OracleCommand 构造函数中。

您可以做几件事。其一,ExecuteNonQuery 通常 returns 受影响的行。可能只是您的 where 子句未识别任何记录并且更新影响了 0 行。如果您确定应该发生更新,您可以确认 ExecuteNonQuery 返回 > 0 并以其他方式抛出错误。在这种情况下至少设置 "result=false"。

第二,您 could/should 在回滚后重新抛出 catch 中的错误。

作为相关的侧边栏,我将只使用 System.Transactions 和 TransactionScope 对象。然后你不需要传递事务或连接。在这种情况下,您确实需要确保 OraMTSRecovery 服务是 运行,但无论如何,所有 ODP.net 安装都附带了它。

我通过添加

解决了这个问题

qry.BindByName = 真

因为我的 ID 参数是第一个设置的,但在查询中它是最后一个(在查询的 where 部分)。

再次感谢您的建议。我会调查 systems.transactions。这是我第一次尝试使用事务,也是第一次使用 Oracle。