Otis wrote:
No, there's a difference. The only object which controls a transaction is the DataAccessAdapter. So a unitofwork can't contain a transaction object, a passed on adapter does. As you pass in a DataAccessAdapter (and not calling a method on it), it might be that it already controls a transaction and then you have two options: commit it or not. Also, perhaps you want to keep the transaction open which is started by the unitofwork.
There are 2 overloads of UnitOfWork2.Commit: one which does and which which doesn't accept a flag for autocommit. The default behavior for the one which doesn't accept an autocommit flag is that it doesn't do an autocommit. This is done because you pass in a dataaccessadapter, and you have to commit the transaction yourself.
But this is my whole point
Say:
The DataAccessAdapter DOES NOT have a transaction in progress.
It is passed to UnitOfWork.Commit.
UnitOfWork starts a transaction on the DataAccessAdapter.
UnitOfWork calls Save(s) / Delete(s) on DataAccessAdapter.
UnitOfWork returns. Default behaviour is "not" to autocommit.
DataAccessAdapter now has an "open" transaction.
The user is now responsible for committing a transaction he did not explicity start. I dont know of any other area of LLBLGen where there is a similar pending transaction as a result of a call to core method other than adapter.StartTransaction...
On the other hand say:
The DataAccessAdapter DOES have a transaction in progress.
It is passed to UnitOfWork.Commit.
UnitOfWork DOES NOT start another transaction as one in already in progress.
UnitOfWork calls Save(s) / Delete(s) on DataAccessAdapter.
UnitOfWork returns. Default behaviour is "not" to autocommit.
DataAccessAdapter now has an "open" transaction. (as expected)
In this instance I would expect DataAccessAdapter to have an open transaction as I was the one who started it... If I had called UnitOfWork.Commit with autoCommit = true, then my entire transaction would have committed which is more than likely not what I would want...
I just think that given there is no support for nested transactions, I like the way LLBLGen is clever enough on the DataAccessAdapter Save methods to work around this problem. The starting and committing of the internal transaction is "hidden" from the user. The Save method returns leaving my transaction state "unchanged".
But I simply noticed that with UnitOfWork, the internal transaction (abeit not "owned" by UnitOfWork) does change state (by default) after the call. And this is something that caused me a bug until I realised that I needed to call it specifying the autoCommit flag (using uow.Commit(adapter, !adapter.IsTransactionInProgress)
in order to maintain transaction state after the call returns.
Maybe it's just me
, but I think the default behaviour is far more confusion than having transaction state "unchanged" after the Commit methods returns...