Print Thread
Cached Updates, ApplyUpdates inserts twice!
#43231 01/30/12 05:36 PM
Joined: Jan 2012
Posts: 5
Cambridge, MA
B
bmarple Offline OP
Member
OP Offline
Member
B
Joined: Jan 2012
Posts: 5
Cambridge, MA
I have a situation where I have master and detail tables, using TOracleDataset with CachedUpdates True. I insert a record into the master, post, then Session.ApplyUpdates([master], False). I add some detail records, post, then Session.ApplyUpdates([detail], False). I then make some more changes to the master record, post, and finally go to commit: session.ApplyUpdates([master, detail], True). I do not have Master set in the detail dataset - I apply the keys manually in OnNewRecord.

I get an Oracle Key Violation on the master table when I apply the second update. Why? Looking at Oracle Monitor I see that DOA tries to insert the same master record twice; once with each ApplyUpdates.

I am using Delphi XE and DOA 4.1.

Re: Cached Updates, ApplyUpdates inserts twice!
bmarple #43234 01/30/12 08:15 PM
Joined: Jan 2012
Posts: 5
Cambridge, MA
B
bmarple Offline OP
Member
OP Offline
Member
B
Joined: Jan 2012
Posts: 5
Cambridge, MA
My understanding, correct me if I'm wrong, is that with CachedUpdates on changes to TOracleDataset values are stored in memory and can be accessed through field variables such as od_MyDataSetMYFIELD.AsInteger. However, a query cannot be run to get the values entered in that dataset until they have been passed onto Oracle by ApplyUpdates (no commit). At this point, TOracleDataset flushes local Cache. At this point I can query from Oracle the data that came from the dataset.

All this appears to be true. BUT, TOracleDataset still has the original query state in Cache despite having had the cache flushed and the sql applied to Oracle by ApplyUpdates([x],False). Why would a subsequent application of ApplyUpdates([x], True) write the same query as the previous one that was flushed?

In the case of an Insert query, why would, after flushing cache and sending the statement to Oracle, uncommitted, be replicated again when updates have been made that need to be passed on to Oracle after the insert statement has already been passed?

I'm confused.

Re: Cached Updates, ApplyUpdates inserts twice!
bmarple #43237 01/31/12 11:07 AM
Joined: Aug 1999
Posts: 22,219
Member
Offline
Member
Joined: Aug 1999
Posts: 22,219
When using CachedUpdates, each dataset has a local change log where all updates are cached. When calling ApplyUpdates, these local changes are applied to the database. When calling CommitUpdates, the transaction is committed, and the local change logs of the datasets are cleared. If you only call Commit, then the local change logs remain and subsequent calls to ApplyUpdates will apply the same changes again, which will lead to errors.


Marco Kalter
Allround Automations
Re: Cached Updates, ApplyUpdates inserts twice!
Marco Kalter #43242 01/31/12 01:25 PM
Joined: Jan 2012
Posts: 5
Cambridge, MA
B
bmarple Offline OP
Member
OP Offline
Member
B
Joined: Jan 2012
Posts: 5
Cambridge, MA
Ok. Let me see if I understand.

When using CachedUpdates, each dataset has a local change log where all updates are cached. Yup.

When calling ApplyUpdates, these local changes are applied to the database. Yup.

When calling CommitUpdates, the transaction is committed, and the local change logs of the datasets are cleared. Yup.

If you only call Commit, then the local change logs remain and subsequent calls to ApplyUpdates will apply the same changes again, which will lead to errors. Yup. But that's not what I'm doing.

In pseudo code this is what I do and what I expect is happening.

. Insert new master record with keys. --In local cache.
. Enter master record data. --In local cache.
. ApplyUpdates([master], False) --Write to Oracle, empty cache.
. Insert detail record with keys. --In local cache.
. Enter detail record data. --In local cache.
. ApplyUpdates([detail], False) -Write to Oracle, empty cache.
. Make more changes to master record. --In local cache.
. ApplyUpdates([master, detail], True)

This is where I get fuzzy. I think that the last apply updates writes out only the changes since the last apply updates for the dataset and commits the transaction. If this is not the case and the cache is written out in its entirety then of course I'll have problems. (All evidence points to this being the case)

What I want to know is, if the above is true, how do I create, edit and post cached data to Oracle in a master detail arrangement such that I can roll back the whole transaction if desired? And that will allow me to run queries against inserted but uncommitted data within the session?


Last edited by bmarple; 01/31/12 01:30 PM.
Re: Cached Updates, ApplyUpdates inserts twice!
bmarple #43251 02/01/12 11:27 AM
Joined: Aug 1999
Posts: 22,219
Member
Offline
Member
Joined: Aug 1999
Posts: 22,219
You should only call ApplyUpdates once for a transaction. After that you can call CommitUpdates, CancelUpdates, or Rollback for transaction management.


Marco Kalter
Allround Automations
Re: Cached Updates, ApplyUpdates inserts twice!
Marco Kalter #43256 02/01/12 01:12 PM
Joined: Jan 2012
Posts: 5
Cambridge, MA
B
bmarple Offline OP
Member
OP Offline
Member
B
Joined: Jan 2012
Posts: 5
Cambridge, MA
So, I cannot apply the updates to Oracle then query them back in different form and add more data all in the same transaction? Bummer.

Is there no way I can flush the cache after a ApplyUpdates([x], False)?

Last edited by bmarple; 02/01/12 01:21 PM.
Re: Cached Updates, ApplyUpdates inserts twice!
bmarple #43260 02/01/12 02:33 PM
Joined: Jan 2012
Posts: 5
Cambridge, MA
B
bmarple Offline OP
Member
OP Offline
Member
B
Joined: Jan 2012
Posts: 5
Cambridge, MA
I found my solution!

If, after I perform session.ApplyUpdates([master,detail], False) I then perform master.CommitUpdates and detail.CommitUpdates the cached changes for the two datasets are flushed, the changes are now in Oracle's transaction cache, I can query the results and I can then make for changes and start the process all over again without error. At the end I can then Session.Commit or Session.Rollback.

The CommitUpdates method of the TOracleDataset appears to flush the cache and refresh the dataset as necessary. Perfect!

Why isn't TOracleDataset.CommitUpdates in the documentation?


Moderated by  support 

Link Copied to Clipboard
Powered by UBB.threads™ PHP Forum Software 7.7.4
(Release build 20200307)
Responsive Width:

PHP: 7.1.33 Page Time: 0.062s Queries: 14 (0.025s) Memory: 2.5299 MB (Peak: 3.0421 MB) Data Comp: Off Server Time: 2024-05-15 10:16:37 UTC
Valid HTML 5 and Valid CSS