In Sql Server 2008 r2, I have a table called Emp, and I’m trying to update some values in a transaction (outer tran), now after the update and before the commit, I began another transaction, in witch i tried to select data from the same table (Emp) but via a loopback linked server.
the tsql look like this:
USE MASTER
GO
EXEC sp_addlinkedserver @server = N'loopback',@srvproduct=N'',@provider = N'SQLNCLI', @datasrc = @@SERVERNAME,@catalog = 'MstrDtl'
GO
EXEC sp_serveroption loopback,N'remote proc transaction promotion','FALSE'
Go
create SYNONYM loopy FOR loopback.MstrDtl.dbo.Emp
use MstrDtl
BEGIN TRAN OuterTran
BEGIN
update table dbo.Emp set Salary = 123456 where Name='abcdx'
BEGIN TRAN InnerTran
select Salary from loopy where Name = 'abcdx'
COMMIT TRAN InnerTran
ROLLBACK TRAN OuterTran
END
so i have two questions:
- can i get old values (the affected rows with the update) in the query to loopback inside the InnerTran using this way?
- the query never stops, any idea?
To answer your questions:
No, you cannot get the old values in that way; you’ll get blocked (see #2) or you’ll get the new values.
The reason the query never stops is because you’re blocking yourself (technically, you’re deadlocking yourself.) Your outer transaction is holding a lock on that row (page actually) and therefore the loopback query is blocked until the update lock is released. You could (but shouldn’t) specify WITH (NOLOCK) on your loopback query but that will actually return the updated but uncommitted row.
If you want the OLD values in your query use the OUTPUT clause. http://msdn.microsoft.com/en-us/library/ms177564.aspx