tags:

views:

369

answers:

3

Is there any way to tell, using just the ADODB.Connection object, whether or not it is currently involved in a transaction?

I'd love to be able to test this on the connect object itself, without relying on keeping a boolean next to it updated.

A: 

It looks like you can check the ADO state. http://msdn.microsoft.com/en-us/library/ms675068%28v=VS.85%29.aspx

You probably already know this other part but I'll post it anyway.

This explains how the transactions work with ADO in VB. http://support.microsoft.com/kb/198024

Thomas Schultz
I don't think you can. This was the first place I looked, and it looks like the state values don't have anything to say about being in a transaction or not. See: http://msdn.microsoft.com/en-us/library/ms675546%28v=VS.85%29.aspx
Tom Tresansky
A: 

You can't unless you track it yourself. The connection object doesn't have a property dealing with transaction state. You'll have to have your proc set a flag in another table/settings area if you HAVE to have it (which can be problematic if unhandled errors occur and the state flag ever gets "stuck" with an invalid status, you need come up with a valid "timeout" or override to ignore/kill/overwrite the previous).

jasonk
+2  A: 

The BeginTrans method can be used as a function that returns the nesting level of the transaction. If you create a property to store this you can check it where ever you need to to see if it is greater than 0. When you commit or rollback you will need to decrement the property yourself.

Private m_TransLevel As Long

Public Property Get TransactionLevel() As Long
    TransactionLevel = m_TransLevel
End Property
Public Property Let TransactionLevel(vLevel As Long)
    m_TransLevel = vLevel
End Property

Public Sub SaveMyData()

    TransactionLevel = adoConnection.BeginTrans()
    ...

End Sub

You could also adapt the return value to work inside a function that returns True/False if the level > 1. I don't like this as well, but it would look something like this (without error handling)

Public Function IsConnectionInsideTransaction(ByVal vADOConnection as ADOBD.Connection) As Boolean
    Dim intLevel As Integer

    If vADOConnection.State = AdStateOpen Then
        intLevel = vADOConnection.BeginTrans()
        IsConnectionInsideTransaction = (intLevel > 1)
        vADOConnection.RollbackTrans
    End If

End Function
Beaner
I've thought about variations of the first method, essentially wrapping the ADODB.Connection in a new MyConnection class which would add this and other functionality. Wanted to minimize changes to the existing code if possible thought. The second way answers my question, I suppose, but seems very risky to me, I don't actually want to be interacting with the database each time I check... Thanks for the suggestions!
Tom Tresansky
Wrapping with your own connection class could have some other advantages. If you ever need to upgrade to VB.net, it might be easier if you have wrapped all ADO objects in your own objects. You could make them have similar signatures to the ADO (to minimize changes to existing code) but only expose the minimum of functionality, to limit the scope of the upgrade effort. I'd suggest putting them in a DLL project so the main project doesn't even reference ADO. Full disclosure: we haven't done this completely in our own projects, but I wish we had.
MarkJ
If only our reporting engine used a wrapper around `ADODB.Connection`! I've toyed with the idea to minimize changes to the existing report extraction code so that users can run reports over a wireless connection (which in our case goes through a custom RPC server).
Mike Spross