Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 implicit_transactions и exists()  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
if @@trancount > 0
 rollback;
 
set implicit_transactions on;

if exists(select * from sys.objects)
 print 1;
select 'exists', @@trancount;

select 1;
select 'select', @@trancount;

select 1 where exists(select * from sys.objects);
select 'select + exists', @@trancount;

if @@trancount > 0
 rollback;

set implicit_transactions off;

Есть ли объективные причины такого поведения?
14 фев 13, 14:18    [13926294]     Ответить | Цитировать Сообщить модератору
 Re: implicit_transactions и exists()  [new]
Crimean
Member

Откуда:
Сообщений: 13147
похоже, важен "факт аутпута" селекта. ну или намерение вычитки (в смысле "наружу") данных. меняем

select 1

на, скажем

select 1 from sys.objects where 0=1;

и получаем уже открытую транзакцию после этого оператора
14 фев 13, 14:44    [13926519]     Ответить | Цитировать Сообщить модератору
 Re: implicit_transactions и exists()  [new]
DmitryZ78
Member

Откуда: Каменск-Уральский
Сообщений: 87
invm,

совсем не обязательно exists

set implicit_transactions on;
select top 1 * from sys.objects;
select  @@trancount;
14 фев 13, 14:48    [13926549]     Ответить | Цитировать Сообщить модератору
 Re: implicit_transactions и exists()  [new]
DmitryZ78
Member

Откуда: Каменск-Уральский
Сообщений: 87
invm,

совсем не обязательно exists

set implicit_transactions on;
select top 1 * from sys.objects;
select  @@trancount;
14 фев 13, 14:52    [13926576]     Ответить | Цитировать Сообщить модератору
 Re: implicit_transactions и exists()  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
Crimean
похоже, важен "факт аутпута" селекта. ну или намерение вычитки (в смысле "наружу") данных
Возможно.
В моем понимании, if exists(...), если там есть обращение или намерение обращения к данным, также должен стартовать транзакцию. Иначе, в режиме неявных транзакций, мы имеем вероятность различных результатов выполнения одного и того же кода, в зависимости от места его вызова. На что и нарвался в одном приложении.
14 фев 13, 15:07    [13926733]     Ответить | Цитировать Сообщить модератору
 Re: implicit_transactions и exists()  [new]
Crimean
Member

Откуда:
Сообщений: 13147
invm,

формально, "if exists" отсутствует в перечне операторов, которые стартуют транзакцию :)
14 фев 13, 15:18    [13926819]     Ответить | Цитировать Сообщить модератору
 Re: implicit_transactions и exists()  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
Crimean
invm,

формально, "if exists" отсутствует в перечне операторов, которые стартуют транзакцию :)
Ну, формально, merge там тоже отсутствует :) И, опять же формально, выполнение select 1 должно стартовать транзакцию. Ну и, согласно BOL, exists содержит инструкцию select, так что снова формально транзакция должна стартовать :)
14 фев 13, 15:26    [13926869]     Ответить | Цитировать Сообщить модератору
 Re: implicit_transactions и exists()  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
Еще один артефакт режима неявных транзакций, который для использующих подобный шаблон хранимок, может стать сюрпризом:
use tempdb;
go

create procedure dbo.spTest
as
begin
 declare @tc int = @@trancount;
 
 if @tc = 0
  begin tran;
 
 begin try
  select 'inner', @@trancount;

  if @tc = 0 and @@trancount > 0
   commit;
 end try
 begin catch
  if @tc = 0 and @@trancount > 0
   rollback;
 end catch;
end;
go

if @@trancount > 0
 rollback;

set implicit_transactions on;

select 'outer', @@trancount;
exec dbo.spTest;
select 'outer', @@trancount;

if @@trancount > 0
 rollback;

set implicit_transactions off;
go
 
drop procedure dbo.spTest;
Наличие открытой транзакции после вызова процедуры в принципе объяснимо. Но где тогда ошибка 266?
14 фев 13, 17:16    [13927758]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить