Question on ACID properties

  • stevro (9/20/2012)


    The other possible query I can think of is SELECT INTO. This wont guarantee Atomicity and Consistency as the INTO table might still be created even if the transaction was rolled back. I think this is a SQL Server design fault

    Did you try that?

    BEGIN TRAN

    SELECT * INTO Gone FROM sys.objects AS o

    ROLLBACK TRAN

    SELECT * FROM Gone

    I have read in Paul NielNielsen Server bible 2008 that in the simple recovery model transactions wont guarantee the durability principle?

    Nope, he's either wrong or is using a very extreme definition of 'durable'

    The durability requirement states that once a transaction commits, the changes it made are permanent within the database. They are, once the commit has occurred, a change cannot be rolled back and the fact that the changes are hardened in the log ensures SQL will replay them if there's a crash immediately after the commit.

    If we were to use Paul's definition, then no recovery model in SQL guarantees durability as if the server SAN catches fire the second after the commit, the changes that transaction made will disappear (along with the rest of the DB)

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • Sean Lange (9/20/2012)


    The other possible query I can think of is SELECT INTO. This wont guarantee Atomicity and Consistency as the INTO table might still be created even if the transaction was rolled back

    Where did you find this? I don't think that is true at all. The rollback would remove the table.

    begin transaction

    select 5 as Col1 into SomeSillyTable

    rollback transaction

    select * from SomeSillyTable

    Yep. Here are the messages I get when I run the code:

    (1 row(s) affected)

    Msg 208, Level 16, State 1, Line 7

    Invalid object name 'SomeSillyTable'.

  • Where did you find this? I don't think that is true at all. The rollback would remove the table.

    begin transaction

    select 5 as Col1 into SomeSillyTable

    rollback transaction

    select * from SomeSillyTable

    Yes, for explicit transactions it will roll back fine, but not for implicit ones:

    select 5/0 as Col1 into SomeSillyTable

    select * from SomeSillyTable

    ..Still creates that silly little table, even though it rolled back the transaction..

  • Nope, he's either wrong or is using a very extreme definition of 'durable'

    Yes, I think you are right on the "extreme" definition, but he is clearly wrong if he states that the Full recovery model will then be durable. As you said, in this case nothing is durable..

  • That's not an implicit transaction, that's auto-commit mode. Implicit transactions is when you have SET IMPLICIT TRANSACTIONS ON.

    The create table doesn't roll back for the same reason the create table doesn't roll back in this example

    BEGIN TRAN

    CREATE TABLE SillyTable (SomeVal int)

    INSERT INTO SillyTable

    SELECT 1/0

    COMMIT TRANSACTION

    A select into is not a single operation, it's 2 individual operations each in auto-commit mode, the first a DDL operation that creates the table, the second a DML that allocates the pages and inserts the rows. The error rolls back the second, not the first.

    Errors don't automatically cause transaction rollbacks.

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • stevro (9/20/2012)


    Where did you find this? I don't think that is true at all. The rollback would remove the table.

    begin transaction

    select 5 as Col1 into SomeSillyTable

    rollback transaction

    select * from SomeSillyTable

    Yes, for explicit transactions it will roll back fine, but not for implicit ones:

    select 5/0 as Col1 into SomeSillyTable

    select * from SomeSillyTable

    ..Still creates that silly little table, even though it rolled back the transaction..

    SELECT INTO is a proprietary carryover from Sybase Transact-SQL and it likely was maintained to behave this way for backward compatibility. I do not agree with the implementation. I think the table creation should be rolled back in case of the failed insert.

    The creation of the table ahead of time appears to be a bit of syntax sugar but there are minimal logging optimizations with SELECT INTO that take it beyond my standard classification of sugar. The behavior is easily worked around using code setup as Sean showed and that would not affect any of the logging optimizations mentioned.

    There are no special teachers of virtue, because virtue is taught by the whole community.
    --Plato

  • GilaMonster (9/20/2012)

    The create table doesn't roll back for the same reason the create table doesn't roll back in this example

    BEGIN TRAN

    CREATE TABLE SillyTable (SomeVal int)

    INSERT INTO SillyTable

    SELECT 1/0

    COMMIT TRANSACTION

    A select into is not a single operation, it's 2 individual operations each in auto-commit mode, the first a DDL operation that creates the table, the second a DML that allocates the pages and inserts the rows. The error rolls back the second, not the first.

    Errors don't automatically cause transaction rollbacks.

    This is not the same. The reason this is not rolled back is because XACT_ABORT is set to OFF on your client.(the deafult for SSMS, but OLEDB this is set on by default). We cant conrol this behaviour with SELECT INTO:

    SET XACT_ABORT ON;

    BEGIN TRAN

    CREATE TABLE SillyTable1 (SomeVal int)

    INSERT INTO SillyTable1

    SELECT 1/0

    COMMIT TRANSACTION;

    SELECT 1/0 As SomeVal INTO SillyTable2;

    The creation of SillyTable1 will be rolled back but not SillyTable2

    I agree as you said that it is two individual operations, but going back to the original question, that is just the point I am making. It is still not and Atomic statement.

    I agree with opc.three that is should not be implemented that way.

  • stevro (9/21/2012)


    I agree as you said that it is two individual operations, but going back to the original question, that is just the point I am making. It is still not and Atomic statement.

    Statements are not atomic. Transactions are. Now, most statements are wrapped into individual transactions, select into however is two transactions, not one. Hence why it rolls back in two pieces.

    Atomic doesn't mean that if any part fails the entire thing will be rolled back (because that doesn't happen by default). It means if the transaction does not complete (the commit isn't reached), no part of the transaction will complete.

    p.s. Ok, the example I gave was not equivalent. This is the equivalent of the select into

    BEGIN TRANSACTION

    CREATE TABLE SillyTable1 (SomeVal int)

    COMMIT TRANSACTION

    BEGIN TRANSACTION

    INSERT INTO SillyTable1

    SELECT 1/0

    COMMIT TRANSACTION

    And yes, I have xact abort off. I don't like automatic rollbacks in the case of errors, I like to handle my errors.

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • GilaMonster (9/21/2012)


    Statements are not atomic.

    Atomicity is a database principle(all or nothing), it is not to say it can/cant belong to something like a statement. You probably meant that they dont ensure atomicity like transactions.

    The only single statement I know of that is not atomic is SELECT INTO. It is not Atomic because as you said it consist of is two different transactions.

    Again, going back to the original question, the only two queries/single statements that I can think of that does not conform to the ACID principles are Select INTO and NOLOCK queries. There might be others?

    Obviously, if we are talking explicit transactions or batches with multiple statements, then it is not applicable and is a new discussion.

    And yes, I have xact abort off. I don't like automatic rollbacks in the case of errors, I like to handle my errors.

    I allways like to have XACT_ABORT set to ON. It does not stop me from handling my errors, but ensure that any uncatchable/unhandled client errors like timeouts will be rolled back.

  • stevro (9/21/2012)


    Again, going back to the original question, the only two queries/single statements that I can think of that does not conform to the ACID principles are Select INTO and NOLOCK queries. There might be others?

    Probably. I'd suspect some of the DDL statements are done as multiple transactions. Easy enough to check if you want.

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass

Viewing 10 posts - 16 through 24 (of 24 total)

You must be logged in to reply to this topic. Login to reply