Remember those college  days when your calculus professor will ask questions such as prove  that cosine 90 is zero?  No? Ok, take it easy, its not coming back to haunt you anymore. Have you ever thought writing SQL stored procedure with or without Begin End will execute differently? To be frank, I have never thought about it. I started writing SQL queries more than a decade ago and almost every single stored procedure l wrote had a  “Begin End”. It is my preferred way even though stored procedures can be written without “Begin End”. This past week l was faced with a challenge when a friend said using “Begin End” in a stored procedure causes it to start a transaction when it runs. I was shocked and started panicking how l have to go back over many stored procedures to remove “Begin End” and it was Friday evening. You know what l mean? I was preparing to go enjoy a nice weekend not worrying myself about “Begin End” causing a deadlock in one of my applications. l always explicitly use “Begin Transaction”  clause whenever l need a piece of code to run as a transaction. I didn’t believe my friend’s assertion so l  decided to test it out to proof whether he is right or not. Personally I prefer testing out technical hypothesis people claim that are not documented so l came up with four simple stored procedures below to show that “Begin End” in a stored procedure does not make any difference. In SQL server, whenever a transaction is started, the global variable @@TRANCOUNT is increased by 1 so l relied on this metadata to show that “Begin End” in a stored procedure does  not automatically start a transaction.

USE 2smart4school

GO

CREATE PROCEDURE dbo.AutotransactionMaker1

AS

BEGIN

SELECT @@TRANCOUNT AS TransactionCount

END

GO

CREATE PROCEDURE dbo.AutotransactionMaker2

AS

SELECT @@TRANCOUNT AS TransactionCount

GO

CREATE PROCEDURE dbo.AutotransactionMaker3

AS

BEGIN

BEGIN TRANSACTION T

SELECT @@TRANCOUNT AS TransactionCount

COMMIT TRANSACTION T

END

GO

CREATE PROCEDURE dbo.AutotransactionMaker4

AS

BEGIN TRANSACTION T

SELECT @@TRANCOUNT AS TransactionCount

COMMIT TRANSACTION T

GO

 

I ran the four procedures and the results showed  a transaction only starts when l use the Begin Transaction clause. Just  a heads up though, SQL Server always perform actions using its ACID property to keep the database in a stable state but if you haven’t explicitly started a  transaction in a stored procedure and a piece of statement in the stored procedure completes execution before any other part of the stored procedure fails, the part that executed successfully will not be rolled back. If you intend the stored procedure executes as a unit a.k.a all or nothing, then you have to explicitly put the block of code in a transaction using

BEGIN TRANSACTION transactionName

do something

COMMIT TRANSACTION transactionName

The best approach is to use a try catch for your code so if a transaction fails, you can either do some other stuff or just rollback any activity that happened earlier. For example

BEGIN TRY

BEGIN TRANSACTION T1

do something

COMMIT TRANSACTION T1

END TRY

BEGIN CATCH

do something

ROLLBACK TRANSACTION T1

END CATCH

This approach makes your code better and robust. If you need only part of the code in your stored procedure to be performed as a unit, then put only that part in a transaction. Don’t put the whole code in a transaction block. Remember when you start a transaction, all tables referred in the transaction will be locked to prevent any modification until the transaction is complete. Other sessions or processes can however perform dirty reads on tables referred in your transaction block but you have to be careful and be aware of the data risk when performing such actions. Do you think there is any difference between a stored procedure with or without “Begin End”? Share it!

Leave a Reply

Your email address will not be published. Required fields are marked *

Name *