Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = %ld, current count = %ld.
If a stored procedure exits with the @@TRANCOUNT value that is not the same as when the stored procedure was entered, Microsoft® SQL Server™ returns error 266.
Note This error can be ignored because it only sends a message to the client and does not affect execution.
This example reproduces the problem:
CREATE PROCEDURE test
AS
SELECT @@TRANCOUNT
ROLLBACK TRANSACTION
SELECT @@TRANCOUNT
GO
BEGIN TRANSACTION
EXECUTE test
GO
Because @@TRANCOUNT is not the same in both SELECT statements, error 266 is generated on return from the stored procedure.
This is expected behavior, but it does not mean that transactions cannot be started, completed, or terminated in a stored procedure. Instead, care must be taken so that the @@TRANSACTION function matches on both entry and exit of the stored procedure. For more information, see ROLLBACK TRANSACTION.
This problem is more likely to occur when writing nested stored procedures.
There is solution so that the stored procedure works without the error. The following is a list of solutions, with sample code for each:
-- Example 1.a
CREATE PROCEDURE test1a
AS
SELECT @@TRANCOUNT
GO
BEGIN TRANSACTION
EXECUTE test1a
ROLLBACK TRANSACTION
GO
-- Example 1.b
CREATE PROCEDURE test1c
AS
SELECT @@TRANCOUNT
GO
CREATE PROCEDURE test1b
AS
BEGIN TRANSACTION
EXEC test1c
COMMIT TRANSACTION
GO
EXECUTE test1b
GO
Note The transaction is not committed until @@TRANCOUNT is equal to 0 (zero).
-- Example 2
CREATE PROCEDURE test2b
AS
SELECT @@TRANCOUNT
BEGIN TRANSACTION
SELECT @@TRANCOUNT
COMMIT TRANSACTION
SELECT @@TRANCOUNT
GO
CREATE PROCEDURE test2a
AS
BEGIN TRANSACTION
EXECUTE test2b
COMMIT TRANSACTION
GO
EXECUTE test2a
GO
-- Example 3
USE master
EXECUTE sp_addmessage 50001, 16, 'Rollback of transaction in test3'
GO
CREATE PROCEDURE test3
AS
RAISERROR (50001,16,1)
GO
BEGIN TRANSACTION
EXEC test3
IF @@error <> 50001
BEGIN
PRINT 'Commit'
COMMIT TRANSACTION
END
ELSE
BEGIN
PRINT 'Rollback'
ROLLBACK TRANSACTION
END
GO
-- Example 4
CREATE TABLE x (col1 int)
GO
CREATE TRIGGER xins
ON x
FOR INSERT AS
ROLLBACK TRANSACTION
GO
CREATE PROCEDURE sp_xinsert
AS
SELECT @@TRANCOUNT
INSERT x (col1) VALUES (1)
SELECT @@TRANCOUNT
GO
BEGIN TRANSACTION
EXECUTE sp_xinsert
IF @@error <> 0
BEGIN
PRINT 'Commit'
COMMIT TRANSACTION
END
ELSE
BEGIN
PRINT 'Rollback'
ROLLBACK TRANSACTION
END
GO
SELECT *
FROM x
@@ERROR | Errors 1 - 999 |
@@TRANCOUNT | EXECUTE |
BEGIN TRANSACTION | ROLLBACK TRANSACTION |
COMMIT TRANSACTION | Transactions |