Subject Calling Commit on TIBODatabase forces Post on all components in edit or insert mode without explicit transactions
Author

First off I know using the global transaction functionality is not ideal, but this is we have a lot of legacy code using it since this was formerly a BDE base product and the global transaction was the only option.

We have a log of legacy code using queries and table components that don't explicitly utilize transactions.  When they post changes the transaction is automatically started and committed.  We also have a number of places in legacy code where transactions were required to ensure consistency in the case of a failure.  This old (originally BDE based) code uses the StartTransaction and Commit methods on the database component.  The utilizes the same global transaction as the components that don't reference transactions.  

We have found that now that we have migrated to IBO the following scenario can occur which did not happen when we were using BDE.  In one screen someone makes a change on a data-bound control backed by a TIBOTable which causes it to go in to edit mode.  They then, before saving changes, can go to another screen and perform an operation that is explicitly wrapping the database changes in a transaction.  Because the transaction is the old global transaction, when the commit happens in the second screen IBO is apparently forcing all datasets not bound to an explicitly defined transaction to Post.  I am assuming IBO is trying to be helpful and Post unposted work at that time.  BDE did not do this. 

Beyond being unexpected behavior that doesn't mimic the BDE controls that IBO replaced, this can lead to errors in the application.  For instance we have found a screen where there is a Save button which contains validation logic as well as other required logic that must happen before saving the record by calling Post.  By having IBO decide to call the Post itself, it bypassed this logic and caused bad data to be saved to the database.

If you have two components that don't specify a transaction and the code doesn't call StartTransaction / Commit on the database component then they work fine. This is only a problem when you have components that don't specify a transaction along with other components/queries you intend to be wrapped in a transaction.  We can fix this on our own but it is painful.  In cases where we just need to instantiate a transaction and attach it to a few queries it is no big deal.  But many of our screens utilize utility classes that perform database operations.  When those are used we then have to plumb the transaction to them so they can uses it if provided.  Those classes themselves may use other classes which also need the transaction provided to them.  It has taken us a week of work to migrate a single screen and all it's dependencies to use an explicitly instantiated transaction instead of the global one.  Doing a search I see that there are at least 60 other places in our code where this needs to be done before we have fully removed using the TIBODatabase component's transaction methods.  Some I'm sure will be easy, but I bet others will be the same complicated quagmire this screen has been with confusing legacy code and deep dependencies that need to be updated to use IBO transactions.

Here is my question.  Is there a way to have IBO operate like BDE did?  If we call StartTransaction / Commit on the database component, we don't want that operation to try and call Post on all other datasets in edit or insert mode.  The way it appears that it use to work was that datasets in those states would automatically start and commit the global transaction at the point at which we called Post on them explicitly.  Can IBO let the TDataset components operate using this old workflow and not call Post automatically?