Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Nested Transactions

Author  Topic 

sujosh
Yak Posting Veteran

55 Posts

Posted - 2005-07-20 : 16:43:33
Here is my problem

There ae 3 SP

SP1 calls SP2
SP2 inserts into TableA
Commits
SP2 Calls SP3

SP3 inserts TableB where a column is a FK from Table A
Commits

The problem is when SP3 tries to insert into TAble B I get an Insert error saying "Insert statment conflicted with FK......" My insert from SP3 is expecting the record that I inserted from SP2 on Table A.


I think the records inserted into Table A gets committed only after the last Commit. How can I make it commit in the nested commit tran?

Thanks

TG
Master Smack Fu Yak Hacker

6065 Posts

Posted - 2005-07-20 : 17:42:06
One way to handle this is to:
Let the calling SP control a single transaction. Use return codes to inform the controlling SP as to whether it should commit or rollback.

Here is a simple example to illustrate the idea:

--Create tables
create table tbA (invoiceid int identity(1,1) primary key, InvoiceDate datetime)
go
create table tbB (invoiceid int references tbA (invoiceid), lineitemid int identity(1,1) primary key, productid int)
go

--------------------------------------------------------------------
--create called SP
create proc tbB_ins
@invoiceid int
,@productid int
as
set nocount on
insert tbB (invoiceid, productid)
values (@invoiceid, @productid)

if @@error = 0
return 0

return -1

go

--------------------------------------------------------------------
--create main, transaction controling SP
create proc tbA_ins
@productid int
as
set nocount on
declare @invid int
,@returnCode int
begin tran

insert tbA (InvoiceDate)
values (getdate())
select @invid = scope_identity()

if @invid > 2
goto onError

if @invid is not null
begin
exec @returnCode = tbB_ins @invoiceid = @invid, @productid = @productid
end

if @returnCode = 0
begin
commit transaction
return 0
end


OnError:

if @@trancount > 0
rollback transaction

raiserror('transaction rolled back', 10,1)
return -1

go
--------------------------------------------------------------------

declare @rc int

--first 2 calls will succeed
exec @rc = tbA_ins @productid = 10
if @rc = 0 print 'transaction completed'

exec @rc = tbA_ins @productid = 11
if @rc = 0 print 'transaction completed'

----third call will fail and transaction will rollback
exec @rc = tbA_ins @productid = 12
if @rc = 0 print 'transaction completed'

--select * from tbA
--select * from tbB
--------------------------------------------------------------------
--clean up

drop proc tbA_ins
drop proc tbB_ins
go
drop table tbB
go
drop table tbA


Be One with the Optimizer
TG
Go to Top of Page

sujosh
Yak Posting Veteran

55 Posts

Posted - 2005-07-20 : 17:52:22
Thanks TG! Appreciate it
Go to Top of Page
   

- Advertisement -