 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Borland Guest
|
Posted: Wed Mar 03, 2004 6:20 am Post subject: The Trouble With Transactions |
|
|
I am using Delphi 6 with SQL 2000 (and MSDE) through TADOConnection and a
TADOCommand.
I have two tables
InvoiceHeader
InvoiceDetail
For the purposes of this test I am always inserting a unique PK into the
Header table and duplicate PKs into the detail table
Transaction 1
INSERT INTO InvoiceHeader (HPK, Total) VALUES (1, 100)
INSERT INTO InvoiceDetail(DPK, Item) VALUES (1, 'ABC')
INSERT INTO InvoiceDetail(DPK, Item) VALUES (2, 'DEF')
Transaction 2
INSERT INTO InvoiceHeader (HPK, Total) VALUES (2, 200)
INSERT INTO InvoiceDetail(DPK, Item) VALUES (1, 'ABC')
INSERT INTO InvoiceDetail(DPK, Item) VALUES (2, 'DEF')
My code goes something like this
con.BeginTrans
com.Execute
try
con.CommitTrans
except
ShowMessage('Error')
end
Assuming empty tables
- The first transaction commits just fine and I see 1 row in the header
table and 2 rows in the detail table.
- The second transaction does NOT fire an exception and worse I see 2 rows
in the header table and 2 rows in the detail table.
I did some playing around and found that if I check con.Errors.Count after
the Execute I can see that an error (or more) has occured and then decide to
not commit the transaction
con.BeginTrans
com.Execute
if con.Errors.Count <> 0 then begin
con.RollbackTrans;
end else begin
try
con.CommitTrans
except
ShowMessage('Error')
end;
end;
But this is not how I expected it to work at all. When I look around for
examples on how to do transactions with Delphi & ADO I always see a
variation of the first piece of code.
I did some more experimentation and found that if I execute the three
inserts as three separate Execute commands before doing a commit I got the
same results as the first case (the first statement gets committed and the
last two do not).
From what I can gather, ADO treats each statement within the command text as
a separate transaction regardless of my stating con.BeginTrans. As well, ADO
doesn't seem to consider a PK Violation as an exception which I find odd.
Does this correspond to what anybody else has found?
Have I missed a setting that I should be aware of?
Any enlightenment would be much appreciated
Richard Speiss
|
|
| Back to top |
|
 |
Rolf Hesterberg Guest
|
Posted: Wed Mar 03, 2004 8:52 am Post subject: Re: The Trouble With Transactions |
|
|
Hi
You are from Borland and you don't know the answer?
| Quote: | Transaction 1
INSERT INTO InvoiceHeader (HPK, Total) VALUES (1, 100)
INSERT INTO InvoiceDetail(DPK, Item) VALUES (1, 'ABC')
INSERT INTO InvoiceDetail(DPK, Item) VALUES (2, 'DEF')
|
You'd rather use:
try
con.BeginTrans;
ADOCommand.CommandText:=....
ADOCommand.Execute;
con.CommitTrans;
except
con.RollbackTrans;
ShowMessage('Error');
end
Why don't you store the primary key of InvoiceHeader in InvoiceDetail?
Should it not be:
INSERT INTO InvoiceHeader (HPK, Total) VALUES (1, 100)
INSERT INTO InvoiceDetail (DPK, HFK, Item) VALUES (1, 1, 'ABC')
INSERT INTO InvoiceDetail(DPK, HFK, Item) VALUES (2, 1, 'DEF')
where HFK is the foreign key in InvoiceDetail, which has to be equal to HPK?
| Quote: | From what I can gather, ADO treats each statement within the command text
as
a separate transaction regardless of my stating con.BeginTrans. As well,
ADO
doesn't seem to consider a PK Violation as an exception which I find odd.
|
Did you declare the foreign key in InvoiceDetail?
Good luck
Rolf Hesterberg
|
|
| Back to top |
|
 |
Viatcheslav V. Vassiliev Guest
|
Posted: Wed Mar 03, 2004 11:40 am Post subject: Re: The Trouble With Transactions |
|
|
| Quote: | try
con.BeginTrans;
|
should be
con.BeginTrans;
try
If you get exception in BeginTrans you should not call RollbackTrans.
//------------------------------------------
Regards,
Vassiliev V. V.
http://www.managed-vcl.com - using .Net objects in Delphi for Win32 +
ADO.Net
http://www.oledbdirect.com - The fastest way to access MS SQL Server,
MS Jet (Access) and Interbase (through OLEDB)
"Rolf Hesterberg" <r.hesterberg (AT) heimsoft (DOT) ch> сообщил/сообщила в новостях
следующее: news:40459cd6$1 (AT) newsgroups (DOT) borland.com...
| Quote: |
Hi
You are from Borland and you don't know the answer?
Transaction 1
INSERT INTO InvoiceHeader (HPK, Total) VALUES (1, 100)
INSERT INTO InvoiceDetail(DPK, Item) VALUES (1, 'ABC')
INSERT INTO InvoiceDetail(DPK, Item) VALUES (2, 'DEF')
You'd rather use:
try
con.BeginTrans;
ADOCommand.CommandText:=....
ADOCommand.Execute;
con.CommitTrans;
except
con.RollbackTrans;
ShowMessage('Error');
end
Why don't you store the primary key of InvoiceHeader in InvoiceDetail?
Should it not be:
INSERT INTO InvoiceHeader (HPK, Total) VALUES (1, 100)
INSERT INTO InvoiceDetail (DPK, HFK, Item) VALUES (1, 1, 'ABC')
INSERT INTO InvoiceDetail(DPK, HFK, Item) VALUES (2, 1, 'DEF')
where HFK is the foreign key in InvoiceDetail, which has to be equal to
HPK?
From what I can gather, ADO treats each statement within the command
text
as
a separate transaction regardless of my stating con.BeginTrans. As well,
ADO
doesn't seem to consider a PK Violation as an exception which I find
odd.
Did you declare the foreign key in InvoiceDetail?
Good luck
Rolf Hesterberg
|
|
|
| Back to top |
|
 |
Richard Speiss Guest
|
Posted: Wed Mar 03, 2004 1:32 pm Post subject: Re: The Trouble With Transactions |
|
|
Oops, I had my newsgroup reader configuration wrong.
The point I was making is that an exception is not fired in the case of a pk
violation. Your code doesn't doesn't work either. But you are right about
having the begin and end in the try block. My real code actual does that
but I didn't type it in correctly when I was making my example.
My example was a simplified case to illustrate what is happening. I
actually do store the pk of the header in the detail but I needed something
that would case the error I was talking about
Thanks for thinking about it though
Richard
"Rolf Hesterberg" <r.hesterberg (AT) heimsoft (DOT) ch> wrote
| Quote: |
Hi
You are from Borland and you don't know the answer?
Transaction 1
INSERT INTO InvoiceHeader (HPK, Total) VALUES (1, 100)
INSERT INTO InvoiceDetail(DPK, Item) VALUES (1, 'ABC')
INSERT INTO InvoiceDetail(DPK, Item) VALUES (2, 'DEF')
You'd rather use:
try
con.BeginTrans;
ADOCommand.CommandText:=....
ADOCommand.Execute;
con.CommitTrans;
except
con.RollbackTrans;
ShowMessage('Error');
end
Why don't you store the primary key of InvoiceHeader in InvoiceDetail?
Should it not be:
INSERT INTO InvoiceHeader (HPK, Total) VALUES (1, 100)
INSERT INTO InvoiceDetail (DPK, HFK, Item) VALUES (1, 1, 'ABC')
INSERT INTO InvoiceDetail(DPK, HFK, Item) VALUES (2, 1, 'DEF')
where HFK is the foreign key in InvoiceDetail, which has to be equal to
HPK?
From what I can gather, ADO treats each statement within the command
text
as
a separate transaction regardless of my stating con.BeginTrans. As well,
ADO
doesn't seem to consider a PK Violation as an exception which I find
odd.
Did you declare the foreign key in InvoiceDetail?
Good luck
Rolf Hesterberg
|
|
|
| Back to top |
|
 |
Rolf Hesterberg Guest
|
Posted: Thu Mar 04, 2004 7:44 am Post subject: Re: The Trouble With Transactions |
|
|
Hi Viatcheslav
| Quote: | should be
con.BeginTrans;
try
If you get exception in BeginTrans you should not call RollbackTrans.
|
That's wright.
Rolf Hesterberg
|
|
| Back to top |
|
 |
Rolf Hesterberg Guest
|
Posted: Thu Mar 04, 2004 8:00 am Post subject: Re: The Trouble With Transactions |
|
|
Hi Richard
| Quote: | Your code doesn't doesn't work either.
|
You use
INSERT INTO InvoiceDetail (DPK, HFK, Item) VALUES (1, 1, 'ABC')
What is the primary key in your InvoiceDetail?
Are there unique keys in your InvoiceDetail?
Rolf Hesterberg
|
|
| Back to top |
|
 |
Richard Speiss Guest
|
Posted: Thu Mar 04, 2004 1:08 pm Post subject: Re: The Trouble With Transactions |
|
|
DPK is the detail primary key.
The INSERT commands are designed to generate the error to show that ADO is
not generating an exception when a key violation occurs
I am working around the problem by testing con.Errors.Count after the
Execute to see if there are problems.
I am merely trying to point out that you can't depend on an exception being
raised
Richard
"Rolf Hesterberg" <r.hesterberg (AT) heimsoft (DOT) ch> wrote
| Quote: | Hi Richard
Your code doesn't doesn't work either.
You use
INSERT INTO InvoiceDetail (DPK, HFK, Item) VALUES (1, 1, 'ABC')
What is the primary key in your InvoiceDetail?
Are there unique keys in your InvoiceDetail?
Rolf Hesterberg
|
|
|
| Back to top |
|
 |
|
|
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
|
|