Click here to Skip to main content
15,893,381 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
Hi everyone,

I'm having two sqlconnections that I'm trying to test. I purposely put some error on the second sql commandtext to force it to rollback everything, but I'm having an error when it hits the TransHQ.Rollback() in the second catch block. I knew about the "zombie transaction" thing, but all of my two connections are still open. Maybe I missed something.
This is my code:
VB
Try
    sqloCnHQ.Open()
    TransHQ = sqloCnHQ.BeginTransaction()
    cmdHQ.Transaction = TransHQ
    cmdHQ.Connection = sqloCnHQ
    cmdHQ.CommandText = SqlHQ.ToString()
    cmdHQ.CommandTimeout = 0
    cmdHQ.ExecuteNonQuery()
    TransHQ.Commit()
Catch ex As Exception
    Application.DoEvents()
    TransHQ.Rollback()
    ErrorHandling("Sync Transactions " & cmdHQ.ToString)
    SyncMessageOPT += "Sync Transactions " + cmdHQ.ToString + Environment.NewLine
    sqloCnHQ.Dispose()
    Err.Clear()
    Exit Sub
End Try


Try
    sqloCnLocal.Open()
    TransLocal = sqloCnLocal.BeginTransaction()
    cmdLocal.Transaction = TransLocal
    cmdLocal.Connection = sqloCnLocal
    cmdLocal.CommandText = SqlLocal.ToString() + "xxx"
    cmdLocal.CommandTimeout = 0
    cmdLocal.ExecuteNonQuery()
    TransLocal.Commit()
Catch ex As Exception
    Application.DoEvents()
    TransHQ.Rollback()
    TransLocal.Rollback()
    ErrorHandling("Sync Transactions " & cmdLocal.ToString)
    SyncMessageOPT += "Sync Transactions " + cmdLocal.ToString + Environment.NewLine
    sqloCnHQ.Dispose()
    sqloCnLocal.Dispose()
    Err.Clear()
    Exit Sub
End Try

sqloCnHQ.Dispose()
sqloCnLocal.Dispose()


Thanks in advance!
Posted
Comments
FrankNight 17-Sep-15 4:53am    
Yes, you are missing something.
You need a "distributed transaction" that means a transaction across multiple database or connection.
You cannot manage it so simply.

Your code don't work because when you commit a transaction, it cannot be more rollbacked.

You can begin both transaction and commit (or rollback) in the same try/catch but is not a good practice.

Look for somthing like two-phase commit algorithm.
http://www.codeproject.com/Articles/143421/Two-Phase-Commit-Protocol

1 solution

Hi,

Thanks for the idea. I manage to get it right, but I'm not sure if what I did will have a drawback.I simply put the two commit statements after the second ExecuteNonQuery.
VB
sqloCnLocal.Open()
TransLocal = sqloCnLocal.BeginTransaction()
cmdLocal.Transaction = TransLocal
cmdLocal.Connection = sqloCnLocal
cmdLocal.CommandText = SqlLocal.ToString() + "xxx"
cmdLocal.CommandTimeout = 0
cmdLocal.ExecuteNonQuery()

TransHQ.Commit()
TransLocal.Commit()


So the idea is not to commit first until the whole execution finished.

Thanks for the great help!
 
Share this answer
 
Comments
FrankNight 18-Sep-15 4:53am    
Yes, this is the only simple thing you can do.
Drawbacks are if something goes wrong between the 2 commit. something with network, system availability, db error, etc...
good luck ;-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900