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 tablescreate table tbA (invoiceid int identity(1,1) primary key, InvoiceDate datetime)gocreate table tbB (invoiceid int references tbA (invoiceid), lineitemid int identity(1,1) primary key, productid int)go----------------------------------------------------------------------create called SPcreate proc tbB_ins@invoiceid int,@productid intasset nocount oninsert tbB (invoiceid, productid)values (@invoiceid, @productid)if @@error = 0 return 0return -1go----------------------------------------------------------------------create main, transaction controling SPcreate proc tbA_ins @productid intasset nocount ondeclare @invid int ,@returnCode intbegin 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 endOnError: if @@trancount > 0 rollback transactionraiserror('transaction rolled back', 10,1)return -1go--------------------------------------------------------------------declare @rc int--first 2 calls will succeedexec @rc = tbA_ins @productid = 10if @rc = 0 print 'transaction completed'exec @rc = tbA_ins @productid = 11if @rc = 0 print 'transaction completed'----third call will fail and transaction will rollbackexec @rc = tbA_ins @productid = 12if @rc = 0 print 'transaction completed'--select * from tbA--select * from tbB----------------------------------------------------------------------clean updrop proc tbA_insdrop proc tbB_insgodrop table tbBgodrop table tbABe One with the OptimizerTG