Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
Есть два сервера MS SQL Server 2005 прилинкованные друг к другу: Server1, Server2

На Server1 есть база DB1, в которой есть табличка:
T1 table (t_date datetime)


и процедура:
procedure proc1
as
begin
  insert into T1(t_date) select getdate()
end


На Server2 есть процедура:
procedure proc2
as
begin
  ...
  exec Server1.DB1.dbo.proc1
end


В MS SQL Management Studio подключаюсь к Server2 и выполняю процедуру proc2. В результате чего в таблице T1 на Server1 появляется 1 запись. Если выполняю процедуру из клиента, то появляется 2 записи с разным временем. В коде, который показан как "..." есть вставки в локальные таблицы и записи не множатся, что свидетельствует о том, что процедура proc2 выполняется 1 раз.

Почему на удаленном сервере происходит 2 выполнения proc1?
4 июл 12, 10:40    [12814106]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
mr.Guest
Почему на удаленном сервере происходит 2 выполнения proc1?

Потому что ваш клиент запускает ее 2 раза

mr.Guest
В коде, который показан как "..." есть вставки в локальные таблицы и записи не множатся, что свидетельствует о том, что процедура proc2 выполняется 1 раз.

Используйте не теоритические рассуждения, а практический мониторинг происходящих не сервере событий.
4 июл 12, 10:42    [12814126]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
автор
Потому что ваш клиент запускает ее 2 раза

Клиент её не запускает. Клиент запускает процедуру proc2 (1 раз!), а вот уже она запускает proc1 на удаленном сервере.

Попробовал реализовать такую схему: Создал на Server2 таблицу T2, аналогичную T1. Код proc1 перенес в proc2.

procedure proc2
as
begin
  ...

  insert into T2 (t_date) select getdate()
  exec Server1.DB1.dbo.proc1
end


В результате выполнения появляется 1 запись в T2, и две записи в T1.
4 июл 12, 11:26    [12814518]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
mr.Guest
Клиент её не запускает.Клиент запускает процедуру proc2 (1 раз!)

Вы это видели в профайлере ? Или вы просто считаете ваш клиентский код идеальным ?
4 июл 12, 11:28    [12814533]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
1. Видел в профайлере.
2. Видел клиентский код.
3. Видел результат выполнения proc2.
4 июл 12, 11:31    [12814577]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
mr.Guest
1. Видел в профайлере.

Видели 2 раза выполнение Server1.DB1.dbo.proc1 ?
4 июл 12, 11:33    [12814607]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
Я смотрел в профайлере:
1. Что происходит между клиентом и Server2
Происходит 1 вызов proc2.
2. Что происходит на Server1.
Происходит 2 вызова proc1 по учетной записи указанной в линке серверов.

Именно поэтому я и задаю вопрос, почему такое может происходить.
4 июл 12, 11:44    [12814773]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
mr.Guest
Я смотрел в профайлере:
1. Что происходит между клиентом и Server2
Происходит 1 вызов proc2.

Какие события вы трассируете ?
Как выглядит код, приходящий с клиента ?
4 июл 12, 11:49    [12814829]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
Для экспериментов пришлось наваять проект с чистого листа. Привожу ВЕСЬ код.

Имеется два прилинкованных MS SQL Server'a.

Выполняем на первом SQL-сервере (название сервера SERVER1, база DBTest1) скрипт:
create table TestTable (t_date datetime)
go

create procedure TestTableInsert
as
begin
	insert into TestTable(t_date) select getdate()
end
go


Выполняем на втором SQL-сервере (название сервера SERVER2, база DBTest2) скрипт:
create procedure TestProcedure1
as
begin
	exec [SERVER1].[DBTest1].dbo.TestTableInsert
	select 1
end
go

create procedure TestProcedure2
as
begin
	exec [SERVER1].[DBTest1].dbo.TestTableInsert
	select 2
end
go


Клиентская часть - форма с одной единственной кнопкой. По нажатию на кнопку подключаемся к SERVER2, каталог DBTest2 под виндовой учеткой (в моем случае о правах думать не надо). После подключения последовательно выполняем две процедуры. И закрываем соединение.

Обработчик клика по кнопке на Delphi:

procedure TForm1.Button1Click(Sender: TObject);
var
  adc: TADOConnection;
  adq: TADOQuery;
begin
  adc:= TADOConnection.Create(Application);
  adc.LoginPrompt:= False;
  adc.ConnectionString:= 'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBTest2;Data Source=SERVER2';

  adq:= TADOQuery.Create(Application);
  adq.Connection:= adc;
  adq.SQL.Text:= 'exec TestProcedure1';
  adq.Open;
  adq.Close;

  adq.SQL.Text:= 'exec TestProcedure2';
  adq.Open;
  adq.Close;

  adc.Close;

  adq.Free;
  adq:= nil;

  adc.Free;
  adc:= nil;
end;


Запускаю клиента, нажимаю на кнопку, закрываю программу.

В таблице SERVER1.DBTest1.dbo.TestTable появляется сразу 4 записи.
4 июл 12, 14:28    [12816317]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
mr.Guest
Запускаю клиента, нажимаю на кнопку, закрываю программу.

И где трасса ВСЕХ команд, которые ваш Delphi отослал серверу ?
4 июл 12, 14:30    [12816327]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
Трассировка между клиентом и SERVER2.
4 июл 12, 14:40    [12816400]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34687
есть вставки в локальные таблицы и записи не множатся, что свидетельствует о том, что процедура proc2 выполняется 1 раз.

не факт, скорее всего процедура выполняется 2 раза, но один раз откатывается транзакция, локально, а удаленно - нет.
4 июл 12, 14:45    [12816426]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
Прошу прощения, картинка не прицепилась, пробую еще раз.

К сообщению приложен файл. Размер - 70Kb
4 июл 12, 14:45    [12816431]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
mr.Guest
Прошу прощения, картинка не прицепилась, пробую еще раз.

Мне кажется, что это трасса только нектоторых событий, а не всех
4 июл 12, 14:49    [12816446]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
aleonov
Member

Откуда:
Сообщений: 96
mr.Guest,



Я так подозреваю что либо не настроен MS DTС либо неправильно сконфигурирован линк сервер, поэтому и разница в кол-ве вставленных записей на локальном и удаленном сервере.


попробуйте вот так

procedure proc2
as
begin
  ...
  begin distributed tran	
  insert into T2 (t_date) select getdate()
  exec Server1.DB1.dbo.proc1
  commit
end


какое значение 'remote proc transaction promotion' у линк сервера ?
4 июл 12, 14:56    [12816487]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
aleonov,

"begin distributed tran" - не помогло.

"remote proc transaction promotion" - в 2005й версии, такого поля нет :(
4 июл 12, 15:11    [12816589]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
aleonov
Member

Откуда:
Сообщений: 96
mr.Guest

"begin distributed tran" - не помогло.

"remote proc transaction promotion" - в 2005й версии, такого поля нет :(


что значит не помогло, ошибки не выдает и вставляет разное кол-во записей ?


В 2005 это называлось remote proc tran
4 июл 12, 15:21    [12816653]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
Glory,

полная трассировка оказалась слишком большой, приводить её не буду.
Разбирая обнаружил следующее: первая процедура запустилась 3 раза. При этом в первый раз она отработала полностью. А два следующих раза только первая строка - собственно вызов удаленной процедуры. А вторая строка "select 1" не выполнялась. Затем полностью отработала вторая процедура. В итоге и добавилось 4 строки.

Попробовал изменить процедуры поменяв местами последовательность команд. Первой строкой select, затем вызов удаленной процедуры:
create procedure TestProcedure1
as
begin
	select 1
	exec [SERVER1].[DBTest1].dbo.TestTableInsert
end
go


Провел тест. Результат положительный. Каждая процедура отработала по одному разу полностью. И в результирующей удаленной таблице две строки. Стало понятно как обойти проблему, но по-прежнему непонятна причина.
4 июл 12, 15:35    [12816777]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
mr.Guest
Стало понятно как обойти проблему, но по-прежнему непонятна причина.

Причина - в кривом клиентском коде Delphi.
Который запуск процедуры делает методом, предназначенным для открытия наборов.
4 июл 12, 15:39    [12816807]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
Glory
Причина - в кривом клиентском коде Delphi.
Который запуск процедуры делает методом, предназначенным для открытия наборов.


Хранимая процедура должна выполнить некоторые действия, часть из которых происходит на удаленном сервере, а в результат выводит набор, который клиент должен отобразить. Можно ли вызов сделать другим способом?
4 июл 12, 15:45    [12816864]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
что значит не помогло, ошибки не выдает и вставляет разное кол-во записей ?

В 2005 это называлось remote proc tran


Ошибки не выдало, результат не изменился.
sp_configure 'remote proc trans'

На обоих серверах одинаково:
name - remote proc trans
minimum - 0
maximum - 1
config_value - 0
run_value - 0
4 июл 12, 15:53    [12816933]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
mr.Guest
полная трассировка оказалась слишком большой, приводить её не буду.

Откуда она вдруг получилась большой для единственного запуска процедуры ?
Интересует трасса всех событий в коннекте, открытым вашим приложением.

mr.Guest
Хранимая процедура должна выполнить некоторые действия, часть из которых происходит на удаленном сервере, а в результат выводит набор, который клиент должен отобразить. Можно ли вызов сделать другим способом?

Разумеется. Достаточно изучить методы ADO.
4 июл 12, 15:54    [12816934]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
aleonov
Member

Откуда:
Сообщений: 96
mr.Guest,

обычно запросы возвращают кол-во обработанных записей, некоторые клиентские приложения обрабатывают такие сообщения и
возможно Delphi также.. добавьте в процедуру в самом начале set nocount on и протестируйте, должно помочь.
4 июл 12, 15:56    [12816959]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
aleonov
Member

Откуда:
Сообщений: 96
mr.Guest
Ошибки не выдало, результат не изменился.


проверяли в MS студии или клиентским приложением ?
4 июл 12, 16:09    [12817043]     Ответить | Цитировать Сообщить модератору
 Re: Двойной запуск удаленной процедуры  [new]
mr.Guest
Guest
Внимательнее просмотрев трассу профайлера и проведя некоторые эксперименты выяснил, что вся проблема растет из связки Delphi-ADO. В некоторых случаях перед непосредственным выполнением запросов SQL-серверу приходит запрос вида:
SET FMTONLY ON [запрос] SET FMTONLY OFF


Если внутри запроса есть вызов удаленных процедур, то они выполняются на удаленном сервере невзирая на состояние FMTONLY. Почему так происходит? Как удаленному серверу объяснить, что запуск происходит в режиме получения метаданных?
6 июл 12, 10:26    [12826824]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить