Home All Groups Group Topic Archive Search About
Author
1 Sep 2006 10:57 AM
rocket salad
Picture this setup: 2 SQL Servers, S1 and S2 are physically seperate. On S1
is sat a stored procedure SP1 and on S2 is sat another, SP2.

SP2 attempts to insert into a temprary table from SP1 using the following
syntax:

insert into #temptable
exec opendatasource('SQLOLEDB','blah blah').db.dbo.SP1

When ran an error is returned stating that a distributed transaction
couldn't be started. However, in no place in any of the code which is running
is a transaction exlpicitly started (no begin or end statements and
definitely no begin transaction statements). In fact this line on it's own
executed in isolation attempts to start a distributed transaction.

If I change SP1 to a view returning the same data and use this code:

insert into #temptable
select * from opendatasource('SQLOLEDB','blah blah').db.dbo.view

no transactions are started and everything runs.

why?

Author
1 Sep 2006 12:14 PM
Peter W. DeBetta
Just out of curiosity, does SP1 do any data modification?

--
Peter DeBetta, MVP - SQL Server
http://sqlblog.com
--
Show quote
"rocket salad" <rocketsa***@discussions.microsoft.com> wrote in message
news:D339288B-4342-4CFD-AFD6-D564D4A40859@microsoft.com...
> Picture this setup: 2 SQL Servers, S1 and S2 are physically seperate. On
> S1
> is sat a stored procedure SP1 and on S2 is sat another, SP2.
>
> SP2 attempts to insert into a temprary table from SP1 using the following
> syntax:
>
> insert into #temptable
> exec opendatasource('SQLOLEDB','blah blah').db.dbo.SP1
>
> When ran an error is returned stating that a distributed transaction
> couldn't be started. However, in no place in any of the code which is
> running
> is a transaction exlpicitly started (no begin or end statements and
> definitely no begin transaction statements). In fact this line on it's own
> executed in isolation attempts to start a distributed transaction.
>
> If I change SP1 to a view returning the same data and use this code:
>
> insert into #temptable
> select * from opendatasource('SQLOLEDB','blah blah').db.dbo.view
>
> no transactions are started and everything runs.
>
> why?
Author
1 Sep 2006 12:25 PM
rocket salad
No - I had chosen a stored procedure instead of a view initially because
there is a high likelyhood of other processing needing to be done when the
select is carried out. It seemed logical to have an sp and call the extra
processing from there, but at that time all SP1 was doing was a select.

Show quote
"Peter W. DeBetta" wrote:

> Just out of curiosity, does SP1 do any data modification?
>
> --
> Peter DeBetta, MVP - SQL Server
> http://sqlblog.com
> --
> "rocket salad" <rocketsa***@discussions.microsoft.com> wrote in message
> news:D339288B-4342-4CFD-AFD6-D564D4A40859@microsoft.com...
> > Picture this setup: 2 SQL Servers, S1 and S2 are physically seperate. On
> > S1
> > is sat a stored procedure SP1 and on S2 is sat another, SP2.
> >
> > SP2 attempts to insert into a temprary table from SP1 using the following
> > syntax:
> >
> > insert into #temptable
> > exec opendatasource('SQLOLEDB','blah blah').db.dbo.SP1
> >
> > When ran an error is returned stating that a distributed transaction
> > couldn't be started. However, in no place in any of the code which is
> > running
> > is a transaction exlpicitly started (no begin or end statements and
> > definitely no begin transaction statements). In fact this line on it's own
> > executed in isolation attempts to start a distributed transaction.
> >
> > If I change SP1 to a view returning the same data and use this code:
> >
> > insert into #temptable
> > select * from opendatasource('SQLOLEDB','blah blah').db.dbo.view
> >
> > no transactions are started and everything runs.
> >
> > why?
>
>
>
Author
1 Sep 2006 11:09 PM
Hugo Kornelis
On Fri, 1 Sep 2006 03:57:01 -0700, rocket salad wrote:

Show quote
>Picture this setup: 2 SQL Servers, S1 and S2 are physically seperate. On S1
>is sat a stored procedure SP1 and on S2 is sat another, SP2.
>
>SP2 attempts to insert into a temprary table from SP1 using the following
>syntax:
>
>insert into #temptable
>exec opendatasource('SQLOLEDB','blah blah').db.dbo.SP1
>
>When ran an error is returned stating that a distributed transaction
>couldn't be started. However, in no place in any of the code which is running
>is a transaction exlpicitly started (no begin or end statements and
>definitely no begin transaction statements). In fact this line on it's own
>executed in isolation attempts to start a distributed transaction.

Hi rocket,

You did start a transaction - each data modification statement always
runs inside a transaction. If you never explicitly start one, then the
execution of the INSERT statement will implicitly start a transaction.
And the SET IMPLICIT_TRANSACTION options determines if it's also
implicitly committed at the end of the statement.

Since SQL Server on server S2 has no idea if SP1 is going to do any
modification or not, it has to assume the worst and hence will expect
the possibility of data modifications from S2.

>If I change SP1 to a view returning the same data and use this code:
>
>insert into #temptable
>select * from opendatasource('SQLOLEDB','blah blah').db.dbo.view
>
>no transactions are started and everything runs.

There's still a transaction started (for the insert), but there's no
distributed transaction. With a SELECT statement, SQL Server *knows*
that there's not going to be any data modification on the other server,
so the transaction can remain local.

--
Hugo Kornelis, SQL Server MVP
Author
4 Sep 2006 8:20 AM
rocket salad
And so fails. I've done another test which was to carry out the 'exec
opendatasource' statement in isolation (without the insert into) and this
executes fine. From this, am I right in thinking that because all S2 is doing
is triggering SP1, that it doesn't care if it runs correctly or not (no
transactions have been explicitly started so there's no different processing
which needs to occur whether SP1 runs or not). When there is an 'insert
into', however, a transaction is needed because if the exec fails then the
insert should fail also.

Is this right?

Show quote
"Hugo Kornelis" wrote:

> On Fri, 1 Sep 2006 03:57:01 -0700, rocket salad wrote:
>
> >Picture this setup: 2 SQL Servers, S1 and S2 are physically seperate. On S1
> >is sat a stored procedure SP1 and on S2 is sat another, SP2.
> >
> >SP2 attempts to insert into a temprary table from SP1 using the following
> >syntax:
> >
> >insert into #temptable
> >exec opendatasource('SQLOLEDB','blah blah').db.dbo.SP1
> >
> >When ran an error is returned stating that a distributed transaction
> >couldn't be started. However, in no place in any of the code which is running
> >is a transaction exlpicitly started (no begin or end statements and
> >definitely no begin transaction statements). In fact this line on it's own
> >executed in isolation attempts to start a distributed transaction.
>
> Hi rocket,
>
> You did start a transaction - each data modification statement always
> runs inside a transaction. If you never explicitly start one, then the
> execution of the INSERT statement will implicitly start a transaction.
> And the SET IMPLICIT_TRANSACTION options determines if it's also
> implicitly committed at the end of the statement.
>
> Since SQL Server on server S2 has no idea if SP1 is going to do any
> modification or not, it has to assume the worst and hence will expect
> the possibility of data modifications from S2.
>
> >If I change SP1 to a view returning the same data and use this code:
> >
> >insert into #temptable
> >select * from opendatasource('SQLOLEDB','blah blah').db.dbo.view
> >
> >no transactions are started and everything runs.
>
> There's still a transaction started (for the insert), but there's no
> distributed transaction. With a SELECT statement, SQL Server *knows*
> that there's not going to be any data modification on the other server,
> so the transaction can remain local.
>
> --
> Hugo Kornelis, SQL Server MVP
>
Author
4 Sep 2006 10:51 PM
Hugo Kornelis
On Mon, 4 Sep 2006 01:20:03 -0700, rocket salad wrote:

>And so fails. I've done another test which was to carry out the 'exec
>opendatasource' statement in isolation (without the insert into) and this
>executes fine. From this, am I right in thinking that because all S2 is doing
>is triggering SP1, that it doesn't care if it runs correctly or not (no
>transactions have been explicitly started so there's no different processing
>which needs to occur whether SP1 runs or not). When there is an 'insert
>into', however, a transaction is needed because if the exec fails then the
>insert should fail also.
>
>Is this right?

Hi Rocket,

Yes.

A transaction is needed because the insert modifies data, and has to be
rolled back in case of error.

A distributed transaction is needed because the stored procedure MIGHT
change data, and in case of error the changes on both servers have to be
rolled back.

--
Hugo Kornelis, SQL Server MVP

AddThis Social Bookmark Button