оператор выбора в транзакции с сервером с обратной связью никогда не останавливается - PullRequest
0 голосов
/ 04 ноября 2010

В Sql Server 2008 r2 у меня есть таблица с именем Emp, и я пытаюсь обновить некоторые значения в транзакции (внешний тран), теперь после обновления и перед фиксацией я начал другую транзакцию, в которой я попытался выбрать данные из той же таблицы (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

поэтому у меня два вопроса:

  • могу ли я получить старые значения (затронутые строки с обновлением) в запросе для обратной связи внутри InnerTran, используя этот способ?
  • запрос никогда не останавливается, есть идеи?

1 Ответ

0 голосов
/ 03 августа 2011

Чтобы ответить на ваши вопросы:

  1. Нет, вы не можете получить старые значения таким образом;Вы будете заблокированы (см. № 2) или получите новые значения.

  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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...