Implicit Transactions
Never messed around with this setting in the server configuration, so I was unfamilar with the impact it would have.If I ran a statement with something like the following:
insert into foo
select bar
insert into foo
select bar
I know that if the first had an aborting error, such as text was too long, the second statement would not complete as the batch would have failed. If you instead did
insert into foo
select bar
GO
insert into foo
select bar
and had the same error, the second would be completed, since the first would throw an error, but the GO separates the second statement explicitly into another batch, and therefore another transaction.
Interestingly, the Implicit Transactions
option changes the behavior to making each statement act as if it was encapsulated by begin transaction --- commit transaction
instead of requiring this to be defined.
So if you set implicit transactions
on and ran the statement below with no go statement:
insert into foo
select bar
insert into foo
select bar
It is really operating as if:
begin transaction
insert into foo
select bar
commit transaction
GO
begin transaction
insert into foo
select bar
commit transaction
MSDN - Implicit Conversions is a resource that further documents the behavior, indicating that a rollback for the particular transaction is handled automatically. This means that since that each statement is treated as a transaction that it will not abort the second statement and terminate execution if the first experinces the error, since by "implicit conversions" this would be handled separately. MSDN article with example code to walk through it https://technet.microsoft.com/en-us/library/ms190230(v=sql.105).aspx
/*******************************************************
STEP 1: SETUP
*******************************************************/
use tempdb;
set nocount on;
set xact_abort off;
set implicit_transactions off;
if object_id('dbo.TestImplicitTrans','U') is not null
begin
print 'Dropped dbo.TestImplicitTrans per existed';
drop table dbo.TestImplicitTrans;
end;
print 'create table dbo.TestImplicitTrans';
create table dbo.TestImplicitTrans
(
test_k int primary key
identity(1,1)
not null
,random_text varchar(5) not null
);
go
/*******************************************************
TEST 1:
xact_abort off
set implicit_transactions off
Results in:
- first transaction fails
- second transaction succeeds (this is due to xact_abort off not being activated)
test_k random_text
2 12345
*******************************************************/
use tempdb;
go
set nocount on;
set xact_abort off;
set implicit_transactions off;
truncate table dbo.TestImplicitTrans;
print 'Statement 1 START';
insert into dbo.TestImplicitTrans (random_text) values ('00001x');
print 'Current trancount: ' + cast(@@trancount as varchar(100));
insert into dbo.TestImplicitTrans (random_text) values ('00002');
print 'Current trancount: ' + cast(@@trancount as varchar(100));
insert into dbo.TestImplicitTrans (random_text) values ('00003');
print 'Successfully inserted: ' + cast(@@rowcount as varchar(10));
print 'Statement 1 END';
print char(13) + char(13) + 'Statement 2 START';
insert into dbo.TestImplicitTrans
(random_text)
values
('12345' -- random_text - varchar(5)
);
print 'Successfully inserted: ' + cast(@@rowcount as varchar(10));
print 'Statement 2 END';
select
*
from
dbo.TestImplicitTrans as TIT;
go
/*******************************************************
TEST 2:
xact_abort on
set implicit_transactions off
Results in:
- first transaction fails
- second transaction doesn't execute due to xact abort being set on
test_k random_text
NONE
*******************************************************/
use tempdb;
go
set nocount on;
set xact_abort on;
set implicit_transactions off;
truncate table dbo.TestImplicitTrans;
print 'Statement 1 START';
insert into dbo.TestImplicitTrans
(random_text)
values
('12345x' -- random_text - varchar(5) ONE CHARACTER TOO LARGE
);
print 'Successfully inserted: ' + cast(@@rowcount as varchar(10));
print 'Statement 1 END';
print char(13) + char(13) + 'Statement 2 START';
insert into dbo.TestImplicitTrans
(random_text)
values
('12345' -- random_text - varchar(5)
);
print 'Successfully inserted: ' + cast(@@rowcount as varchar(10));
print 'Statement 2 END';
select
*
from
dbo.TestImplicitTrans as TIT;
go
/*******************************************************
TEST 2:
xact_abort off
set implicit_transactions off
Results in:
- first transaction fails
- second transaction doesn't execute due to xact abort being set on
test_k random_text
NONE
*******************************************************/
use tempdb;
go
set nocount on;
set xact_abort on;
set implicit_transactions on;
truncate table dbo.TestImplicitTrans;
print 'Statement 1 START';
insert into dbo.TestImplicitTrans
(random_text)
values
('12345x' -- random_text - varchar(5) ONE CHARACTER TOO LARGE
);
print 'Successfully inserted: ' + cast(@@rowcount as varchar(10));
print 'Statement 1 END';
print char(13) + char(13) + 'Statement 2 START';
insert into dbo.TestImplicitTrans
(random_text)
values
('12345' -- random_text - varchar(5)
);
print 'Successfully inserted: ' + cast(@@rowcount as varchar(10));
print 'Statement 2 END';
select
*
from
dbo.TestImplicitTrans as TIT;
go