Database 针对环回链接服务器的事务中的select语句从不停止
在Sql Server 2008 r2中,我有一个名为Emp的表,我正在尝试更新事务外部传输中的一些值,现在在更新之后和提交之前,我开始了另一个事务,在该事务中,我尝试从同一个表Emp中选择数据,但是通过环回链接服务器。 tsql如下所示:Database 针对环回链接服务器的事务中的select语句从不停止,database,tsql,transactions,Database,Tsql,Transactions,在Sql Server 2008 r2中,我有一个名为Emp的表,我正在尝试更新事务外部传输中的一些值,现在在更新之后和提交之前,我开始了另一个事务,在该事务中,我尝试从同一个表Emp中选择数据,但是通过环回链接服务器。 tsql如下所示: USE MASTER GO EXEC sp_addlinkedserver @server = N'loopback',@srvproduct=N'',@provider = N'SQLNCLI', @datasrc = @@SERVERNAME,@ca
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
所以我有两个问题:
我可以用这种方法在查询中更新受影响的行以在InnerTran中回送旧值吗?
问题永远不会停止,知道吗?
回答您的问题: 不,您不能以这种方式获取旧值;您将被阻止,请参见2,否则将获得新值 查询从未停止的原因是,您在技术上封锁了自己,使自己陷入僵局。您的外部事务实际上持有该行页面上的锁,因此在释放更新锁之前,环回查询将被阻止。您可以但不应该在环回查询中指定WITH NOLOCK,但这将实际返回已更新但未提交的行 如果要在查询中使用旧值,请使用OUTPUT子句
CREATE TABLE #emp
(
id INT IDENTITY PRIMARY KEY CLUSTERED,
empName VARCHAR(255),
salary MONEY
)
go
INSERT INTO #emp(empName, salary)
SELECT 'bill', 5000
UNION ALL
SELECT 'ted', 5000
UNION ALL
SELECT 'cheech', 35000
UNION ALL
SELECT 'chong', 15000
UNION ALL
SELECT 'tango', 70000
UNION ALL
SELECT 'Cash', 200000
GO
DECLARE @oldValues TABLE
(
id INT,
empname VARCHAR(255),
salary money
)
UPDATE #emp SET salary = salary + 500
OUTPUT DELETED.* INTO @oldValues
WHERE empName = 'bill'
SELECT E.empName, E.salary AS NewSalary, O.salary AS OldSalary
FROM #emp E
INNER JOIN @oldValues O
ON E.id = O.id
DROP TABLE #emp