I have a problem that is essentially what was briefly discussed in StackOverflow but I want to clarify the philosophy, pattern, and actual use of ADO.Net transactions.
I have a .Net 2.0, VB.Net application that accesses a Sybase database using OleDB.
I many cases that look something like this - starting in the DAL:
Class PersonClass
Public Shared Sub InsertPerson(...)
...oleDBConnection.open()
...oleDBCommand.CommandText = "insert..."
...oleDBCommand.ExecuteNonQuery
...oleDbCommand.Dispose()
...oleDBConnection.close()
End Sub
End Class
Class AddressClass
Public Shared Sub InsertClass(...)
...oleDBConnection.open()
...oleDBCommand.CommandText = "insert..."
...oleDBCommand.ExecuteNonQuery
...oleDbCommand.Dispose()
...oleDBConnection.close()
End Sub
End Class
Now, at the business layer I do something like:
For Each p in personList
p.Insert
For each a in p.addressList
a.Insert
Next
Next
where both the BusPersonClass and BusAddressClass have an Insert method that just invokes the static (shared) Insert method in the associated DAL class.
So with that setup I now want to add transactions. I want the transaction to begin before the loop over personList and end after the loop is complete. It seems that the BL needs to be the one to start the transaction but that sort of database interaction should be abstracted down into the DAL so at most my business Insert method should begin with a call to something like myTransactionClass.Begin and end with a similar call to myTransactionClass.End.
The myTransactionClass should be something defined in the DAL. I also think it is obvious that the properties of that class cannot be static because the transaction object should not be shared among all users of the web app.
Based on the this 15 Seconds article I should really use the TransactionScope. I have some concerns though:
Establishing a transaction based on a call originating in the BL suggests that the DAL needs some kind of private global transaction variable that can persist the memory of the transaction between sequential calls to DAL objects i.e. the separate calls to InsertPerson and InsertAddress. But the TransactionScope discussion and the above StackOverflow thread seems to imply that ADO.Net keeps track of that automatically and transparently. That would seem a little to magical though.
I am tempted to think that to get transactions right one needs to create the OleDbConnection, open it, set its transaction property, and then use that same connection throughout the entire process - holding that connection open across multiple calls to the DAL methods. But that goes against the idea of connection pooling. So does the connection pooling really work that magically or do I need to maintain the connection open?
Using static (shared) methods to get and save data seemed like a great idea it simplified code but if either the connection or the transaction object(s) need to be persisted across various DAL method calls and since making a transaction or connection static across all the web-app users would be disastrous I suspect that shared methods in the DAL are actually "bad".
Are my confusion and concerns clear? Can someone offer suggestions or examples other than simplistic MSDN code snippets that elucidate the proper approach?
Thank you.