.net Oracle Transaction передается классу byRef

У меня есть процесс, в котором я передаю свое соединение с оракулом и транзакцию по ссылке. Все мои вставки/удаления работают нормально. Однако одно из обновлений проходит нормально, однако данные в базе данных не обновляются.

Мне интересно, распоряжаюсь ли я объектом qry незадолго до того, как зафиксирую, и в этом причина. Это моя первая попытка использовать транзакцию оракула, и все образцы, которые я нашел в Интернете, похоже, делают это для каждого метода. Мне нужно убедиться, что он проходит через весь мой процесс, прежде чем я совершу коммит, иначе я хочу откатиться.

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

При обновлении не происходит ошибки, запись никогда не обновляется в БД.


person frmrock164    schedule 06.03.2015    source источник


Ответы (3)


Я не очень хорошо знаком с VB.net, но знаю, что конструктор OracleCommand хочет, чтобы транзакция была третьим параметром. В С# это будет выглядеть так:

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

Поскольку транзакция является объектом, я не думаю, что передавать ее в качестве ссылки необходимо. В C# это не имело бы значения, если бы вы не клонировали объект, что звучит как действительно плохая идея для объекта транзакции базы данных.

Все это говорит о том, что если вы не используете транзакцию, она должна просто обойти вашу открытую транзакцию и, по сути, выполнить автоматическую фиксацию.

Я думаю, что ваш код выдает и ловит исключение. Ваша попытка/уловка просто маскирует реальную проблему, если только я не упустил лодку. У вас есть два параметра в вашем SQL, но привязан только один. Где находится :xyz? Я подозреваю, что это проблема, но если вы хотите, чтобы транзакция использовалась (чтобы вы могли зафиксировать ее в конце), убедитесь, что вы включили ее в свой конструктор OracleCommand.

person Hambone    schedule 07.03.2015

Есть пара вещей, которые вы можете сделать. Во-первых, ExecuteNonQuery обычно возвращает затронутые строки. Возможно, ваше предложение where не идентифицировало никаких записей, и обновление затронуло 0 строк. Если вы уверены, что обновление должно было произойти, вы можете подтвердить, что ExecuteNonQuery вернул > 0, и в противном случае выдать ошибку. По крайней мере, в этом случае установите "result=false".

Во-вторых, вы можете/должны повторно выдать ошибку в своем улове после отката.

В качестве связанной боковой панели я бы просто использовал System.Transactions и объект TransactionScope. Тогда вам не нужно передавать транзакцию или соединение. В этом случае вам нужно убедиться, что служба OraMTSRecovery запущена, но в любом случае это происходит со всеми установками ODP.net.

person b_levitt    schedule 07.03.2015

Я исправил проблему, добавив

qry.BindByName = Истина

Поскольку мой параметр ID устанавливался первым, но в запросе он был последним (в разделе запроса).

Еще раз спасибо за ваш совет. Я посмотрю на system.transactions. Это была моя первая попытка использования транзакций и первый раз использования Oracle.

person frmrock164    schedule 09.03.2015