在Sql Server 2008 r2中,我有一个名为Emp的表,我正在尝试更新事务中的一些值(外部tran),现在更新之后和提交之前,我开始另一个事务,在女巫我尝试从同一个表(Emp)中选择数据,但是通过环回链接服务器。 tsql看起来像这样:
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
所以我有两个问题:
答案 0 :(得分:0)
回答你的问题:
不,你不能以这种方式得到旧的价值观;你会被阻止(见#2)或者你会得到新的价值。
查询永远不会停止的原因是因为你阻塞了自己(从技术上讲,你自己就是死锁。)你的外部事务正在锁定该行(实际上是页面),因此阻止了环回查询直到更新锁定被释放。您可以(但不应该)在您的环回查询中指定WITH(NOLOCK)但实际上会返回更新但未提交的行。
如果希望查询中的OLD值使用OUTPUT子句。 http://msdn.microsoft.com/en-us/library/ms177564.aspx
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