Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a transaction require a try catch?

I am a c# developer learning more TSQL. I wrote a script like this:

begin transaction
--Insert into several tables
end transaction

But I was told that was not a good idea and to use something like this:

BEGIN TRANSACTION;

BEGIN TRY
    -- Generate a constraint violation error.
    DELETE FROM Production.Product
    WHERE ProductID = 980;
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_LINE() AS ErrorLine
        ,ERROR_MESSAGE() AS ErrorMessage;

    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO

I don't see why the second example is more correct. Would the first one not work the same way? It seems the first one would either update all tables, or not at all? I don't see why checking the @@TRANCOUNT is necessary before the commit.

like image 732
Greg Gum Avatar asked May 06 '16 14:05

Greg Gum


People also ask

Is it correct best practice to have the try catch block inside the transaction or should the transaction be inside the try block?

Option A is the correct choice. It is possible for all statements in a transaction to work and then the actual COMMIT to fail, so you keep the COMMIT inside your TRY block so that any failure of the COMMIT will be caught and you can gracefully handle this error and rollback.

How do you write a transaction in SQL?

Following is an example which would delete those records from the table which have age = 25 and then COMMIT the changes in the database. SQL> DELETE FROM CUSTOMERS WHERE AGE = 25; SQL> COMMIT; Thus, two rows from the table would be deleted and the SELECT statement would produce the following result.

What would you do if an exception happens during that transaction SQL?

CATCH. Anything between the BEGIN TRY and END TRY is the code that we want to monitor for an error. So, if an error would have happened inside this TRY statement, the control would have immediately get transferred to the CATCH statement and then it would have started executing code line by line.


1 Answers

Only Open a Transaction once you are inside the try block and just before the actual statement, And commit it straightaway, do not wait for your control to go to the end of the batch to commit your transactions.

Once you are in Try Block and you have opened a transaction, If something goes wrong The control will jump to CATCH block, Simply rollback your transaction there and do other error handling as required.

I have added a little check before actually rolling back the transaction checking for any open transaction using @@ROWCOUNT function, It doesnt really make much sence in this scenario. It is more useful when you are doing some validations checks in your try block before you open a transaction like checking param values and other stuff and raising error in try block if any of the validation checks fail, In that case control will jump to catch block without even opening a transaction there you can check for any open transaction and rollback if there are any open ones. In your case as it is, you really dont need to check for any open transaction as you will not entre the catch block unless something goes wrong inside your transaction.

BEGIN TRY

  BEGIN TRANSACTION 
     -- Multiple Inserts
    INSERT INTO....
    INSERT INTO.... 
    INSERT INTO.... 
 COMMIT TRANSACTION 
    PRINT 'Rows inserted successfully...'

END TRY

BEGIN CATCH 
  IF (@@TRANCOUNT > 0)
   BEGIN
      ROLLBACK TRANSACTION 
      PRINT 'Error detected, all changes reversed'
   END 
    SELECT
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage
END CATCH
like image 163
M.Ali Avatar answered Nov 05 '22 15:11

M.Ali