.net Oracle транзакция, предадена на класа от Ref

Имам процес, при който предавам връзката си с оракул и транзакцията чрез Ref. Всичките ми вмъквания/изтривания изглежда работят добре. Една от актуализациите обаче изглежда се изпълнява добре, но данните в базата данни не се актуализират.

Чудя се дали изхвърлям обекта 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

Не възниква грешка при актуализацията, записът никога не се актуализира в DB.


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


Отговори (3)


Не познавам много добре VB.net, но знам, че конструкторът на OracleCommand иска транзакцията като трети параметър. В C# ще изглежда така:

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

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

Всичко казано дотук, ако не използвате транзакцията, тогава тя трябва просто да заобиколи вашата отворена транзакция и по същество да се ангажира автоматично.

Мисля, че вашият код хвърля и улавя изключение. Вашият опит/улов просто прикрива истинския проблем, освен ако не съм изпуснал лодката. Имате два параметъра във вашия SQL, но сте обвързали само един. Къде е свързан :xyz? Подозирам, че това е проблемът, но ако искате транзакцията да бъде използвана (за да можете да се ангажирате в края), уверете се, че сте я включили във вашия конструктор на OracleCommand.

person Hambone    schedule 07.03.2015

Има няколко неща, които можете да направите. Първо, ExecuteNonQuery обикновено връща засегнатите редове. Може просто вашата клауза where да не е идентифицирала никакви записи и актуализацията да е засегнала 0 реда. Ако сте сигурни, че трябва да е настъпила актуализация, можете да потвърдите, че ExecuteNonQuery е върнало > 0 и да изведете грешка в противен случай. Най-малкото задайте "result=false" в този случай.

Второ, бихте могли/трябва да хвърлите отново грешката във вашия catch след връщане назад.

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

person b_levitt    schedule 07.03.2015

Поправих проблема, като добавих

qry.BindByName = Вярно

Тъй като моят ID параметър беше зададен първи, но в заявката беше последен (в раздела where на заявката).

Благодаря ви отново за съвета. Ще разгледам system.transactions. Това беше първият ми опит да използвам транзакциите и за първи път използвам Oracle.

person frmrock164    schedule 09.03.2015