Board index » delphi » bug in Cached Updates when used in conjunction with Transactions

bug in Cached Updates when used in conjunction with Transactions

First I'm using Delphi 4.

Here is my problem:
If you use the following code and an error happens when you call the
ApplyUpdates for Query2 the changes
that were made to Query1 will be lost.  The Rollback is called so the server
no long has the changes and
Query1 seems to think that it has already sent them.  Now I've sent similar
messages about this but I have
confirmed this over and over again this is happening.
Now when I say they are lost this doesn't mean they are no longer in the
cache as they are it's just that the
query thinks it has sent the data to the server so after you have fixed the
problem with the data in query2
and rerun this code it doesn't sent the changes to the server for Query1.

If any one can see what is wrong with this code please let me know.

Robert Milmine
The Princeton Review

  Database1.StartTransaction;
  try
    if Query1.State in [dsEdit, dsInsert] then
      Query1.Post;
    if Query1.UpdatesPending then
      Query1.ApplyUpdates;

    if Query2.State in [dsEdit, dsInsert] then
      Query2.Post;
    if Query2.UpdatesPending then
      Query2.ApplyUpdates;

    Database1.Commit;
    Query1.CommitUpdates;
    Query2.CommitUpdates;
  except
    Database1.Rollback;
    raise;
  end;

 

Re:bug in Cached Updates when used in conjunction with Transactions


Quote
"Robert Milmine" <Rober...@Review.com> wrote:
>If any one can see what is wrong with this code please let me know.

Robert,

What you are doing is essentially what I do, but I avoid the problem
of errors during ApplyUpdates by making my UI validation more rigorous
than might be necessary. So I haven't had much experience with error
handling and cached updates yet, but that will change when I start to
do some concurrency coding in the near future.

Borland has done, AFAIK, nothing at all to explain how this problem
might be solved. However, I believe that what you are seeing is not so
much a bug as a weak design. Cached updates is so tightly fitted to
the idea of a single dataset that I don't think much work was done
with the multiple-dataset idea, even though Chapter 13 talks a bit
about master/detail handling.

What is missing, of course, is the concept of rollback in cached
updates. CancelUpdates is not useful here because it deletes the
entered changes in the cache and gives the programmer/user no options
for recovery.

When I get into this, I intend to do some experimentation with the
UpdateAction. In your Query1, for example, it may be possible to use
uaSkip to keep the cache intact until Query2 succeeds, then recalling
Query1.ApplyUpdates with a flag to clear it out. For example:

StartTransaction
try
        Q1.ApplyUpdates;
        Q2.ApplyUpdates;
        FClearing := True;
        Q1.ApplyUpdates;
        FClearing := False;
        Q1.CommitUpdates;
        Q2.CommitUpdates;
...... and so on

Then in Q1UpdateRecord, something like this;

begin
        if FClearing then
                begin
                UpdateAction := uaApplied;
                exit;
                end;

    {here you do your regular stuff}
        UpdateAction := uaSkip;
end;

I have no idea whether this will work. And that still doesn't handle
the problem with Q2 if you should get your error on the third of five
records, say. The first two records will have done a uaApplied before
the error shows up. Maybe the solution is to uaSkip everything until
all the changes are applied.

A question for you: why do you do the explicit post before applying
updates? Is that to make sure that UpdatesPending is set?

Phil Cain
--

Re:bug in Cached Updates when used in conjunction with Transactions


The post is just being better safe than sorry.
It's probably not needed but it was put in just in case.

The really sad thing with all of this is if you use the TDatabases
ApplyUpdates you get the same problem. You are right there
really does need to be a RollbackUpdates in the datasets
so that we can tell it that it hasn't really updated the server.
Maybe someone in Inprise will read this and get it added for
the next version.

Robert Milmine
The Princeton Review

Quote
"Philip Cain" <philc...@orelle.com> wrote in message

news:k2gtcsg76muh1ds6l0q3q6s7deitbl4lhl@4ax.com...
Quote
> "Robert Milmine" <Rober...@Review.com> wrote:

> >If any one can see what is wrong with this code please let me know.

> Robert,

> What you are doing is essentially what I do, but I avoid the problem
> of errors during ApplyUpdates by making my UI validation more rigorous
> than might be necessary. So I haven't had much experience with error
> handling and cached updates yet, but that will change when I start to
> do some concurrency coding in the near future.

> Borland has done, AFAIK, nothing at all to explain how this problem
> might be solved. However, I believe that what you are seeing is not so
> much a bug as a weak design. Cached updates is so tightly fitted to
> the idea of a single dataset that I don't think much work was done
> with the multiple-dataset idea, even though Chapter 13 talks a bit
> about master/detail handling.

> What is missing, of course, is the concept of rollback in cached
> updates. CancelUpdates is not useful here because it deletes the
> entered changes in the cache and gives the programmer/user no options
> for recovery.

> When I get into this, I intend to do some experimentation with the
> UpdateAction. In your Query1, for example, it may be possible to use
> uaSkip to keep the cache intact until Query2 succeeds, then recalling
> Query1.ApplyUpdates with a flag to clear it out. For example:

> StartTransaction
> try
> Q1.ApplyUpdates;
> Q2.ApplyUpdates;
> FClearing := True;
> Q1.ApplyUpdates;
> FClearing := False;
> Q1.CommitUpdates;
> Q2.CommitUpdates;
> ...... and so on

> Then in Q1UpdateRecord, something like this;

> begin
> if FClearing then
> begin
> UpdateAction := uaApplied;
> exit;
> end;

>     {here you do your regular stuff}
> UpdateAction := uaSkip;
> end;

> I have no idea whether this will work. And that still doesn't handle
> the problem with Q2 if you should get your error on the third of five
> records, say. The first two records will have done a uaApplied before
> the error shows up. Maybe the solution is to uaSkip everything until
> all the changes are applied.

> A question for you: why do you do the explicit post before applying
> updates? Is that to make sure that UpdatesPending is set?

> Phil Cain
> --

Re:bug in Cached Updates when used in conjunction with Transactions


Phil,

Interesting discussion on cached updates!

I wonder if IBO's implementation of cached updates could handle this
situation... Have you had a look at IBO's cached updates yet?

I do handle multiple datasets quite well and plan to be able to support
detail datasets that even work with multiple master records. (I just have
inserts left to support like this.)

I have yet to build-in all the algorithms for automatically handling the
order of applying records when master detail is (I'm still at the BDE level
here) used but here's the plan: Identify MD relationships and process the
deletes of child records first, then apply edits in all datasets and lastly
inserts in master first and detail last.

Is there a know list of the BDE's CachedUpdates shortcomings anywhere that I
can look at to see if there are other problems in IBO that I can provide a
solutions for?

Thanks,
Jason Wharton
InterBase Developer Initiative
jwhar...@interbase2000.org

Quote
Philip Cain wrote in message ...
>"Robert Milmine" <Rober...@Review.com> wrote:

>>If any one can see what is wrong with this code please let me know.

>Robert,

>What you are doing is essentially what I do, but I avoid the problem
>of errors during ApplyUpdates by making my UI validation more rigorous
>than might be necessary. So I haven't had much experience with error
>handling and cached updates yet, but that will change when I start to
>do some concurrency coding in the near future.

>Borland has done, AFAIK, nothing at all to explain how this problem
>might be solved. However, I believe that what you are seeing is not so
>much a bug as a weak design. Cached updates is so tightly fitted to
>the idea of a single dataset that I don't think much work was done
>with the multiple-dataset idea, even though Chapter 13 talks a bit
>about master/detail handling.

>What is missing, of course, is the concept of rollback in cached
>updates. CancelUpdates is not useful here because it deletes the
>entered changes in the cache and gives the programmer/user no options
>for recovery.

>When I get into this, I intend to do some experimentation with the
>UpdateAction. In your Query1, for example, it may be possible to use
>uaSkip to keep the cache intact until Query2 succeeds, then recalling
>Query1.ApplyUpdates with a flag to clear it out. For example:

>StartTransaction
>try
> Q1.ApplyUpdates;
> Q2.ApplyUpdates;
> FClearing := True;
> Q1.ApplyUpdates;
> FClearing := False;
> Q1.CommitUpdates;
> Q2.CommitUpdates;
>...... and so on

>Then in Q1UpdateRecord, something like this;

>begin
> if FClearing then
> begin
> UpdateAction := uaApplied;
> exit;
> end;

>    {here you do your regular stuff}
> UpdateAction := uaSkip;
>end;

>I have no idea whether this will work. And that still doesn't handle
>the problem with Q2 if you should get your error on the third of five
>records, say. The first two records will have done a uaApplied before
>the error shows up. Maybe the solution is to uaSkip everything until
>all the changes are applied.

>A question for you: why do you do the explicit post before applying
>updates? Is that to make sure that UpdatesPending is set?

>Phil Cain
>--

Re:bug in Cached Updates when used in conjunction with Transactions


Quote
"Jason Wharton" <jwhar...@ibobjects.com> wrote:
>Is there a know list of the BDE's CachedUpdates shortcomings anywhere

Jason,

Not as far as I know. The biggie here is the rollback issue. I believe
that the BDE marks the cache records done on uaApplied and doesn't
revisit the problem if there is a rollback. However, I've never seen
any documentation on it and I don't think there is any.

Phil Cain
--

Re:bug in Cached Updates when used in conjunction with Transactions


On Fri, 10 Mar 2000 16:21:06 -0500, "Robert Milmine"

Quote
<Rober...@Review.com> wrote:
>Here is my problem:
>If you use the following code and an error happens when you call the
>ApplyUpdates for Query2 the changes
>that were made to Query1 will be lost.  The Rollback is called so the server
>no long has the changes and
>Query1 seems to think that it has already sent them.  Now I've sent similar

You are absolutely right! I know about the same problem for a long
time, I have submitted it a few years ago when I used Delphi 3. Never
heard anything about it since, but it's still there. The query should
only consider the changes posted after CommitUpdates has been called,
not one second earlier. But unfortunately that's not how it works. I
have been avoiding Cached Updates ever since, unfortunately you need
them sometimes.

Let's keep hoping...
Bart

Other Threads