.net Oracle Transaction传递给类byRef

时间:2015-03-06 14:34:22

标签: .net oracle odp.net

我有一个进程,我通过我的oracle连接和事务byRef。我所有的插入/删除似乎都工作正常。但是其中一个更新似乎运行得很好,但是数据库中的数据没有更新。

我想知道我是否在我提交前很快处理了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

以下是我的班级更新功能的简单示例..

 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

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

3 个答案:

答案 0 :(得分:0)

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

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

由于交易是一个对象,我不认为将其作为参考传递是必要的。在C#中,除非你克隆了对象,否则这并不重要,这听起来对于数据库事务对象来说是个坏主意。

所有这一切,如果您不使用该交易,那么它应该绕过您的开放交易并基本上自动提交。

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

答案 1 :(得分:0)

你可以做几件事。例如,ExecuteNonQuery通常返回受影响的行。可能只是你的where子句没有识别任何记录而且更新影响了0行。如果您确定应该发生更新,则可以确认ExecuteNonQuery已返回&gt; 0并抛出另一个错误的错误。在这种情况下至少设置“result = false”。

二,你可以/应该在回滚后重新抛出catch中的错误。

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

答案 2 :(得分:0)

我通过添加

解决了这个问题

qry.BindByName = True

由于我的ID参数首先被设置,但在查询中它是最后一个(在查询的where部分)。

再次感谢您的建议。我将研究systems.transactions。这是我第一次尝试使用Oracle的事务和第一次尝试。