Subject Re: R: R: [IBO] Failed to post all datasets
Author Helen Borrie
At 07:33 PM 31/12/2003 +0100, you wrote:

>The purpose is to have one master table with details: if the user cancel the
>edit, every record from detail & master must revert to the original state.
>I have some more questions concerning the IB_Transaction component, may be
>you can explain:
>-what do you mean when you say <..this error fires only if the number of
>"committed" datasets differs>?
>-Is it related to the properties _DatasetCount, _StatementCount,
>_TransactionLinkCount?
>-I noticed that even if Autocommit is false, the transaction starts
>automatically when the state of the attached query change to edit. Does this
>mean that is not necessary to start manually the transaction?

Antonio,
Do you understand that Commit occurs at transaction level, and commits
changes that are *posted* by datasets?

If a change is not posted, then the transaction is being asked to commit
changes that the server has no knowledge of. Autocommit is a client-side
setting, which causes each Commit call to be preceded by a Post of all
datasets...without Autocommit, your application must take care to perform
the Posts of all datasets in the transaction.

The IBO code will call the NeedToPost method of each non-cached
dataset. However, if you have cached datasets, you will need to visit
those datasets yourself and call ApplyUpdates.

In Fb/IB, all updates are a two-step process: a request (sent by posting
the SQL statement that will perform the change) which, if successful,
causes the server to create a new record version structure. IBO implements
this step in the Post method. This new record version is written to disk
but it is not yet visible to any other transaction. It remains as an
uncommitted request, visible only to the transaction that submitted it.

A subsequent Commit (if successful) causes that record version to become
the latest version, visible to all subsequent transactions as well as any
concurrent transactions that are in ReadCommitted isolation. If Rollback
is called instead, the pending new record version is made "obsolete" and
the original version is unlocked and stays current.

Commit and Rollback affect *all* datasets in the transaction, not just the
last one you happened to be operating on.

Caching effectively separates the records in the dataset buffer from the
state of the database, i.e. it tells the transaction "leave me alone, I
will look after my own posting." No changes in the buffer will be posted
until the cached dataset explicitly calls ApplyUpdates. The transaction
"knows" when there is a cached dataset under its umbrella and, thus, it
"knows" when it is being asked to post changes which it doesn't know about.

You can force the transaction to perform ApplyUpdates on its cached
datasets. The transaction has its own ApplyUpdates method, which takes as
an argument a list of names of cached datasets. It has a property
CachedUpdatesPendingCount that you can use to check whether there are
cached datasets that need ApplyUpdates: do this before your Commit call
and make sure you catch exceptions. Cached updates are much more prone to
update conflicts than are non-cached.

Helen