views:

247

answers:

3

I am using Oracle 11g client, with ODP.NET. I am trying to add conditional Transaction handling.

Dim ds As New DataSet()
Dim txn As OracleTransaction
Dim _beginTransaction as Bolean = true
 Using conn As New OracleConnection(ConnString)
            Try
                conn.Open()
                If _beginTransaction Then
                        txn = conn.BeginTransaction(IsolationLevel.Serializable)
                End If

                Dim adapter As OracleDataAdapter = New OracleDataAdapter()
                adapter.SelectCommand = New OracleCommand(sSQL, conn)

                For i As Integer = 0 To UBound(parameters, 1)
                    adapter.SelectCommand.Parameters.Add(parameters(i))
                Next

                adapter.Fill(ds)
                If _beginTransaction Then
                    txn.Commit() //txn is undefined here? why?
                End If


            Catch e As Exception
                txn.Rollback()
            End Try
        End Using

How do I fix txn being nothing / null? The error is: Variable 'txn' is used before it has been assigned a value. A null reference exception could result at runtime. Links or pointers to solutions would be appreciated also.

Edit: Thanks to RichardOD for pointing out that you can not explicitly declare that a transaction cannot be opend up on stored procedures via ODP.NET. I have verified that this is an issue. BUT We still haven't figured out why the error is occuring. I understand that txn is initially given a value w/in an if statement, but being defined outside of the try/catch block should make that irrelevant.... right? Or is that bad coding?

A: 

Assuming _beginTransaction is a boolean have you set it to true before If _beginTransaction Then ?

Also have you committed the previous transaction before starting this one? Oracle can do weird stuff with connection pooling and BeingTransaction.

A long time ago I had a bug similar to this. Have you looked here?

Edit- are you trying to call a .NET stored proc? OracleConnection.BeginTransaction does not support stored procedure calls:

OracleConnection.BeginTransaction is not allowed for .NET stored procedure

RichardOD
yes that is correct . . I will update my question
andrewWinn
In the applicaiton, the second time this method is called is the first time the transaction is opened. The using statement should also take care of disposing the connection . . . right?
andrewWinn
If the connection is pooled (which it likely is) that is when the problems start. New Transaction on an old connection that hasn't committed...
RichardOD
First call to the Database is a select, with no implicit transaction declared . . .
andrewWinn
Try setting Pooling=false in the connection string and see you still have the same problem (obviously don't leave this on)
RichardOD
Pooling=false didn't change anything . . . .
andrewWinn
OK- run out of suggestions now. Presumably you are getting a NullReferenceException being thrown?
RichardOD
Yeah . . . which is the crazy thing. Variable declared -> variable assigned value -> Null ->WTF?!?!?
andrewWinn
OK- one last suggestion- try IsolationLevel.ReadCommitted instead and see what happens?
RichardOD
nope . . . . thanks for everything though.
andrewWinn
Your phrasing seems misleading to me : you can actually execute a stored procedure in a transaction with ODP.NET as a general rule. Your link only states that you cannot create a transaction using ODP.NET when developing a .NET stored procedure (implying server side code). By the way, thanks for the info (I didn't know that).
Mac
@Mac- that's a good point. I should of perhaps stated .NET stored procedure.
RichardOD
A: 

Question: Is it null immediately after being asigned? And if not, when does it become null? If it's null after immediately, it might be the connection pooling stuff. If after getting the adapter from conn or after filling it, then it's even crazier...

But I would try and find out

GilShalit
No, that is the part that has me scratching my head . . . it does have a value and is assigned . . . .
andrewWinn
So it becomes unassigned only when you commit? Surely it happens somewhere beforehand.
GilShalit
Nope, I know . . . added watch and stepped through code (again :( ) step to txn.Commit() ->hit f-10 in VS, falls to Catch block with empty exception
andrewWinn
Well, we have come to distrust ODP (.Net 2.0) after fighting a memory leak (in code we supplied to a customer) in GetOracleDecimal for over a year...Good luck!
GilShalit
Hang on, if the error is "A null reference exception could result at runtime." that's a compilation error, and is there because your assignment is is an IF clause.
GilShalit
ok, the error doesn't occur during compile time, but IF that is the case what would you suggest?
andrewWinn
A: 

Oracle does not require a transaction for selecting data. Why do you try open one?

EDIT:
If your vb code is called from oracle (via .net integration) than there is no transaction support as RichardOD wrote. Please clarify the environment.

The sql statement executed is dynamic and given in sSQL. The command is prepared and given to a DataAdapter that fills a DataSet. Than you can only execute SELECT statements. Otherwise there is no result.

OR

Because the parameters are prepared too. You are calling a stored procedure (without telling the the CommandType is StoredProcedure). One of your parameters is a ref cursor parameter which will fetched into the DataSet. Right?

Oracle does not need explicit transactions as sql server does. Oracle starts an implicit transaction with the first dml statement in your session. The sideeffect is, if you did not start an transaction you cannot commit the implicit transaction. I do not know if there is access to implicit transaction via the connection object.

Christian13467
good question. Technically it is a procedure that is being executed. I am in the process of refactoring the data layer.
andrewWinn
Stored procedure?
RichardOD
@andrewWinn- if you are using a stored procedure I've updated my answer to explain that this won't work.
RichardOD
@andrewWinn: Is this vb code called from plsql integrated into the database? Are you runing on an implicit connection? I'm a bit confused.
Christian13467