BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

MIDAS and transaction

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Databases (Multi-Tier)
View previous topic :: View next topic  
Author Message
Serge Dosyukov
Guest





PostPosted: Tue Jul 29, 2003 1:18 am    Post subject: MIDAS and transaction Reply with quote



Hello, I did use example from "C:Program
FilesBorlandDelphi7DemosMidasEmpEdit"
and log all events occured on a server
Next steps are performed
- server has "resolve to dataset=True"
- Open server
- Open client
- modify first record
- modify second record
- apply updates
- close application

Question: where is a place to put validation on a server?
Is it possible to avoid to be in transaction, because validation could take
a time
According to documentation place will be DSP_UpdateData, but it is in
transaction
DSP_BeforeApplyUpdates also not a good place because there is no place to
access delta... except to work with Data property of the DSP

There is a log:
=====
NoTr : CDS_BeforeOpen
NoTr : CDS_BeforeGetRecords
NoTr : DSP_BeforeGetRecords
NoTr : QRY_BeforeOpen
NoTr : QRY_AfterOpen
NoTr : QRY_AfterScroll
NoTr : DSP_GetData
NoTr : QRY_BeforeScroll
NoTr : QRY_AfterScroll
NoTr : DSP_AfterGetRecords
NoTr : CDS_AfterGetRecords
NoTr : CDS_AfterOpen
NoTr : CDS_AfterScroll
NoTr : CDS_BeforePost
NoTr : CDS_AfterPost
NoTr : CDS_BeforeScroll
NoTr : CDS_AfterScroll
NoTr : CDS_BeforePost
NoTr : CDS_AfterPost
NoTr : DSP_BeforeApplyUpdates
InTr : DSP_UpdateData
InTr : QRY_BeforeScroll
InTr : QRY_AfterScroll
InTr : DSP_BeforeUpdateRecord
InTr : QRY_BeforeScroll
InTr : QRY_AfterScroll
InTr : QRY_BeforePost
InTr : QRY_AfterPost
InTr : DSP_AfterUpdateRecord
InTr : QRY_BeforeScroll
InTr : QRY_AfterScroll
InTr : DSP_BeforeUpdateRecord
InTr : QRY_BeforeScroll
InTr : QRY_AfterScroll
InTr : QRY_BeforePost
InTr : QRY_AfterPost
InTr : DSP_AfterUpdateRecord
InTr : QRY_BeforeScroll
InTr : QRY_AfterScroll
NoTr : DSP_AfterApplyUpdates


--
Serge Dosyukov
Borland Certified Delphi Developer

"Minds are like a parachute. They only work when open."
"Programming is not a job; it is a style of life."

Installation process could be easier. - http://www.dragonsoft.spb.ru/



Back to top
Dave Rowntree
Guest





PostPosted: Tue Jul 29, 2003 11:52 am    Post subject: Re: MIDAS and transaction Reply with quote



"Serge Dosyukov" <serge@argosoftware[DOT]com> wrote:

Quote:
Hello, I did use example from "C:Program
FilesBorlandDelphi7DemosMidasEmpEdit"
and log all events occured on a server
Next steps are performed
- server has "resolve to dataset=True"
- Open server
- Open client
- modify first record
- modify second record
- apply updates
- close application

Why do you want to use ResolveToDataSet=True ? This is not normally a
good selection.

Quote:
Question: where is a place to put validation on a server?

If you want to take some kind of action on a pre-update record basis,
then you could use the DSP.BeforeUpdateRecord event.

Quote:
Is it possible to avoid to be in transaction, because validation could take
a time

Yes, if you do a bit of coding. Instead of using the
DSP.BeforeUpdateRecord event, use the DSP.BeforeApplyUpdates event.
That occurs before a transaction is started. You need to obtain and
pass the Delta into the event using the OwnerData variable:

procedure TForm1.ClientDataSet1BeforeApplyUpdates(Sender: TObject;
var OwnerData: OleVariant);
begin
OwnerData := ClientDataSet1.Delta;
end;

procedure TForm1.DataSetProvider1BeforeApplyUpdates(Sender: TObject;
var OwnerData: OleVariant);
var
cdsTDelta: TPacketDataSet;
begin
cdsTDelta := TPacketDataSet.Create(nil);
try
cdsTDelta.Data := OwnerData;
While not cdsTDelta.Eof do
begin
if cdsTDelta.UpdateStatus = usUnModified then
cdsTDelta.InitAltRecBuffers(True);
case cdsTDelta.UpdateStatus of
usInserted:;
usModified:
if not VarIsEmpty(cdsTDelta.FieldByName('Details').NewValue)
then
; // do something ...
usDeleted:;
end;
cdsTDelta.Next;
end;
finally
FreeAndNil(cdsTDelta);
end;
end;


Using the above code you can step through the cdsTDelta dataset and do
whatever you want.

If you want to abort the ApplyUpdates just raise an exception. That
will raise the exception at the client.

If you want to abort the update but have the abort message appear at
the client as a reconciliation error in the CDS.OnReconcileError event
(which is quite a tidy way to handle a validation update rejection):

1. Create a DSP private field, e.g. FValErrString: string;
2. In the '//do something' code section above set FValErrString to the
error message you want to pass back to the CDS.
3. In the DSP.BeforeUpdateRecord event, raise an exception with
FValErrString as the exception message.
--
Dave Rowntree

Back to top
Serge Dosyukov
Guest





PostPosted: Tue Jul 29, 2003 4:35 pm    Post subject: Re: MIDAS and transaction Reply with quote



"Dave Rowntree" <daver (AT) spam_offbrookswood (DOT) co.uk> wrote

Quote:

Why do you want to use ResolveToDataSet=True ? This is not normally a
good selection.

I use ADO on a server, ADO in some situation provides better auto-mechanizm
for resolving updates in dataset, especially with joins
But aside from this only difference will be this

NoTr : DSP_BeforeApplyUpdates NoTr : DSP_BeforeApplyUpdates
InTr : DSP_UpdateData InTr : DSP_UpdateData
InTr : QRY_BeforeScroll
*******************
InTr : QRY_AfterScroll
*******************
InTr : DSP_BeforeUpdateRecord InTr : DSP_BeforeUpdateRecord
InTr : QRY_BeforeScroll
*******************
InTr : QRY_AfterScroll
*******************
InTr : QRY_BeforePost
*******************
InTr : QRY_AfterPost
*******************
InTr : DSP_AfterUpdateRecord InTr : DSP_AfterUpdateRecord
InTr : QRY_BeforeScroll
*******************
InTr : QRY_AfterScroll
*******************
InTr : DSP_BeforeUpdateRecord InTr : DSP_BeforeUpdateRecord
InTr : QRY_BeforeScroll
*******************
InTr : QRY_AfterScroll
*******************
InTr : QRY_BeforePost
*******************
InTr : QRY_AfterPost
*******************
InTr : DSP_AfterUpdateRecord InTr : DSP_AfterUpdateRecord
InTr : QRY_BeforeScroll
*******************
InTr : QRY_AfterScroll
*******************
NoTr : DSP_AfterApplyUpdates NoTr : DSP_AfterApplyUpdates

So it still keeps us in transaction

Quote:
Question: where is a place to put validation on a server?
If you want to take some kind of action on a pre-update record basis,
then you could use the DSP.BeforeUpdateRecord event.

As I've mentioned, this event already inside transaction, which is not a
good place to perform any pre-validation

Quote:
Is it possible to avoid to be in transaction, because validation could
take
a time

Yes, if you do a bit of coding. Instead of using the
DSP.BeforeUpdateRecord event, use the DSP.BeforeApplyUpdates event.
That occurs before a transaction is started. You need to obtain and
pass the Delta into the event using the OwnerData variable:

This is a not costeffective method because it makes a client packet twice
bigger
Can I use packet information from Data property of DSP instead? If so how to
get a Delta:TPacketDataSet from it?

<skip>
Quote:
Using the above code you can step through the cdsTDelta dataset and do
whatever you want.

If you want to abort the ApplyUpdates just raise an exception. That
will raise the exception at the client.

If you want to abort the update but have the abort message appear at
the client as a reconciliation error in the CDS.OnReconcileError event
(which is quite a tidy way to handle a validation update rejection):

1. Create a DSP private field, e.g. FValErrString: string;
2. In the '//do something' code section above set FValErrString to the
error message you want to pass back to the CDS.
3. In the DSP.BeforeUpdateRecord event, raise an exception with
FValErrString as the exception message.

This is good, I will consider this

Quote:
--
Dave Rowntree



Back to top
Dave Rowntree
Guest





PostPosted: Tue Jul 29, 2003 6:29 pm    Post subject: Re: MIDAS and transaction Reply with quote

"Serge Dosyukov" <serge@argosoftware[DOT]com> wrote:

Quote:
I use ADO on a server, ADO in some situation provides better auto-mechanizm
for resolving updates in dataset, especially with joins

Ok.

<snip>
Quote:
Question: where is a place to put validation on a server?
If you want to take some kind of action on a pre-update record basis,
then you could use the DSP.BeforeUpdateRecord event.

As I've mentioned, this event already inside transaction, which is not a
good place to perform any pre-validation

That depends on the amount of validation you need to do, and the
requirements of the validation. It is often necessary to vet a record
only after previous pending postings have been updated, in which case
this would be the only place to do the validation. Making a
generalised statement that DSP.BeforeUpdateRecord is not a good place
to do validation is incorrect.

Quote:
Is it possible to avoid to be in transaction, because validation could
take
a time

Yes, if you do a bit of coding. Instead of using the
DSP.BeforeUpdateRecord event, use the DSP.BeforeApplyUpdates event.
That occurs before a transaction is started. You need to obtain and
pass the Delta into the event using the OwnerData variable:

This is a not costeffective method because it makes a client packet twice
bigger

This would only be a concideration if your client -> appserver
connection is extremely (ridiculously) slow, the Delta contains a very
large number of updates, or your system is going to have to deal with
extremely large volumes of updates.

If none of the above apply then your generalised statement that:

'This is a not costeffective method because it makes a client packet
twice bigger'

is incorrect. Not cost effective in comparison to what? The fact that
you concider passing an extra copy of a CDS.Delta a problem suggests
you probably have very little knowledge of the size of Delta packets.
A Delta containing 50 new records may well be about 1/2K. This can
vary of course depending on the width of your dataset.

Quote:
Can I use packet information from Data property of DSP instead? If so how to
get a Delta:TPacketDataSet from it?

No, unless you subclass TDataSetProvider and override
TCustomeProvider.ApplyUpdates to put the Delta into OwnerData. That
would make the Delta available in the DSP.BeforeApplyUpdates event.
--
Dave Rowntree

Back to top
Serge Dosyukov
Guest





PostPosted: Wed Jul 30, 2003 12:50 am    Post subject: Re: MIDAS and transaction Reply with quote

"Dave Rowntree" <daver (AT) spam_offbrookswood (DOT) co.uk> wrote

Quote:
"Serge Dosyukov" <serge@argosoftware[DOT]com> wrote:

<snip>
Quote:
Question: where is a place to put validation on a server?
If you want to take some kind of action on a pre-update record basis,
then you could use the DSP.BeforeUpdateRecord event.

As I've mentioned, this event already inside transaction, which is not a
good place to perform any pre-validation

That depends on the amount of validation you need to do, and the
requirements of the validation. It is often necessary to vet a record
only after previous pending postings have been updated, in which case
this would be the only place to do the validation. Making a
generalised statement that DSP.BeforeUpdateRecord is not a good place
to do validation is incorrect.

If you have related records, yes, you're right. but if records is not
related. Then by being in transaction, validation could cause serios
problems...

Quote:
Is it possible to avoid to be in transaction, because validation could
take a time

Yes, if you do a bit of coding. Instead of using the
DSP.BeforeUpdateRecord event, use the DSP.BeforeApplyUpdates event.
That occurs before a transaction is started. You need to obtain and
pass the Delta into the event using the OwnerData variable:

This is a not costeffective method because it makes a client packet twice
bigger

This would only be a concideration if your client -> appserver
connection is extremely (ridiculously) slow, the Delta contains a very
large number of updates, or your system is going to have to deal with
extremely large volumes of updates.
If none of the above apply then your generalised statement that:

'This is a not costeffective method because it makes a client packet
twice bigger'

is incorrect. Not cost effective in comparison to what? The fact that
you concider passing an extra copy of a CDS.Delta a problem suggests
you probably have very little knowledge of the size of Delta packets.
A Delta containing 50 new records may well be about 1/2K. This can
vary of course depending on the width of your dataset.

I do know a structure of Delta packets... FYI Wink
Your approach is correct until, datapacket includes nested tables, Image
fields or any other BLOB based fields
Comments will be from this category... Then packet could *potentially*
became big enough especially passed as a SOAP request/respond

Quote:
Can I use packet information from Data property of DSP instead? If so how
to
get a Delta:TPacketDataSet from it?

No, unless you subclass TDataSetProvider and override
TCustomeProvider.ApplyUpdates to put the Delta into OwnerData. That
would make the Delta available in the DSP.BeforeApplyUpdates event.

Yeah, I've decided to do this...

--
Serge Dosyukov
Borland Certified Delphi Developer

"Programming is not a job; it is a style of life."

Installation process could be easier. - http://www.dragonsoft.spb.ru/



Back to top
Dave Rowntree
Guest





PostPosted: Wed Jul 30, 2003 9:02 am    Post subject: Re: MIDAS and transaction Reply with quote

"Serge Dosyukov" <serge@argosoftware[DOT]com> wrote:
Quote:
If you have related records, yes, you're right. but if records is not
related. Then by being in transaction, validation could cause serios
problems...

If your concern is with executing validation DB calls inside a
transaction, one option could be to open another connection
specifically to do the validation. Whilst this makes slightly more
demand on DB resources for applying updates, the potential system
loadings would have to be fairly high for this to be of much
concequence.

Quote:
I do know a structure of Delta packets... FYI Wink
Your approach is correct until, datapacket includes nested tables, Image
fields or any other BLOB based fields

Again, you are making a very misleading generalised statement. Saying
that Delta packets immediately become unwieldy if a dataset contains a
nested dataset, an image field, or a BLOB based field is simply not
true.

Any overhead added by nested datasets is normally insignificant.
Infact, there are situations were updating say 10 master and 10 detail
records can result in a smaller Delta than updating 20 master records.
As I say, the differences are normally so insignificant as to be of
absolutely no importance. What counts normally is the overall number
of updates per Delta, and the width of the data.

Quote:
Comments will be from this category... Then packet could *potentially*
became big enough especially passed as a SOAP request/respond

The verbosity of SOAP is well known.
--
Dave Rowntree

Back to top
Dave Rowntree
Guest





PostPosted: Fri Aug 01, 2003 10:03 am    Post subject: Re: MIDAS and transaction Reply with quote

"Serge Dosyukov" <serge@argosoftware[DOT]com> wrote:
Quote:
By the way not all event handlers method (DoMyEvent are virtual)

procedure DoAfterUpdateRecord(Sender: TObject; SourceDS: TDataSet;
DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind);
procedure DoBeforeUpdateRecord(Sender: TObject; SourceDS: TDataSet;
DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; var Applied:
Boolean);

are not

So I see. They should IMHO. I have entered QC#5456 requesting they be
added.
--
Dave Rowntree

Back to top
Serge Dosyukov
Guest





PostPosted: Tue Aug 05, 2003 9:34 pm    Post subject: Re: MIDAS and transaction Reply with quote

Thank you, you even post it internally
this is really great ;o)

--
Serge Dosyukov
Borland Certified Delphi Developer
MCP
"Programming is not a job; it is a style of life."

"Dave Rowntree" <daver (AT) spam_offbrookswood (DOT) co.uk> wrote

Quote:
"Serge Dosyukov" <serge@argosoftware[DOT]com> wrote:
By the way not all event handlers method (DoMyEvent are virtual)

procedure DoAfterUpdateRecord(Sender: TObject; SourceDS: TDataSet;
DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind);
procedure DoBeforeUpdateRecord(Sender: TObject; SourceDS: TDataSet;
DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; var Applied:
Boolean);

are not

So I see. They should IMHO. I have entered QC#5456 requesting they be
added.
--
Dave Rowntree



Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Databases (Multi-Tier) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.