Transactions and ApplyUpdates with at least two tables

Hello,

I’ve never really thought about this, but I’ve just noticed than when I call ApplyUpdate for (at least) two not connected datasets and one of them fails (because of concurrent edit), only the “problematic” table will be rollbacked, the other one gets silently commited (although the businessprocessor is configured to raise an exception).

How can I achieve, that one call to ApplyUpdate is processed within a single transaction?

Set DAService.ReturnUpdateFailureDelta to False.

in you have personal BusinessProcessor for these tables, you should set BP.RaiseExceptionAtError to True too.

Hi Evgeny,

I’ve set ReturnUpdateFailureDetla to false, but I still have this issue.
Are there any other settings involved?

only this option is affected.
if error is detected during processing Deltas on server-side, code raises the exception and transaction is roll backed.

If you want, you can send your project to support@, I’ll check what is wrong

Hi Evgeny,

I’ll try to provide a small example over the weekend, but I’ve logged the whole Queries and did not found any rollback.

Hm, that’s really strange:

I just tried to get the point, where the exception should raise within the BP, so that TDataAbstractService.InternalUpdateData calls DoRollbackTransaction… and that never happens.

Normally, I would expect that an exception happens, when a Create/Insert/Update-Statement fails, but in fact, this does not happen in TDABusinessProcessor.ProcessDelta. It is just handled and the “canremove”-flag is set to false. This leads to the situation, that TDADataAbstractService.InternalUpdate executes the “normal” path and calls commit (which in fact, submits all other changes, except the one, that failed) and never a rollback is applied.

I think the main issue here is, that not the command raises an exception (so the except-block within ProcessDelta is never reached), but the command itself is valid but does not update any data. This does not lead to an exeception in currcmd.Execute…

can you check that exception is raised on server-side in TDABusinessProcessor.ProcessDelta during processing “problematic” table and this exception is handled by TDABusinessProcessor.DoProcessErrorEvent?

by default, it should raise EDAApplyUpdateFailed in this method at

  else if FRaiseExceptionAtError then begin
    raise EDAApplyUpdateFailed.Create(aChange, Error); //<<<<<
  end;

Exactly this should happen…

…however, this method gets called only in the except-path within ProcessDelta… but this path will not be used: an update with affectedrows=0 will just set the internal flag “canremove” to false. Neither the server nor some program code will raise any exception… and so there won’t be any call to DoProcessErrorEvent.

Maybe as a side-note: I’m currently using 9.5.0.1371

You can catch this situation in any event that is used in TDABusinessProcessor.DoAfterProcessChangeEvent and raise custom exception

Hm,
Ok, but then the whole usage of RaiseExceptionOnError is questionable:

  • a failure in an update (e.g. a Key-Violation or a constrain) will raise an exception and all deltas will be rolled back (of all tables)
  • a missing update (with updWhereAll) will only skip the missing delta

From my point of view, both situations should be handled as an error (because the DeltaChange is not applied), and so both should behave the same.

And when thinking about updates, I’d like to have them ACID by default and I should not be required to manually add an event.

In fact, the RaiseExceptionOnError should clearly ensure, that the whole transaction should be rolled back…

We handle errors that were raised by Direct Access Components, like PK violation, etc , i.e. errors raised on DB side.
you can handle case when change has csFailed status and raise a custom exception so it will be caught by RaiseExceptionOnError.

Although I still think, that the whole transaction should be rolled back when an Insert/Update/Delete fails (if RaiseExceptionOnError=true), the solution with the CustomEvent is still suitable.

Thanks