Transactions within a Transaction












11















What behaviour would PostgreSQL display if for example the script below were called



BEGIN;
SELECT * FROM foo;
INSERT INTO foo(name) VALUES ('bar');
BEGIN; <- The point of interest
END;


Would PostgreSQL discard the second BEGIN or would a commit be implicitly decided on and then run the BEGIN END block at the end as a separate transaction?










share|improve this question



























    11















    What behaviour would PostgreSQL display if for example the script below were called



    BEGIN;
    SELECT * FROM foo;
    INSERT INTO foo(name) VALUES ('bar');
    BEGIN; <- The point of interest
    END;


    Would PostgreSQL discard the second BEGIN or would a commit be implicitly decided on and then run the BEGIN END block at the end as a separate transaction?










    share|improve this question

























      11












      11








      11


      3






      What behaviour would PostgreSQL display if for example the script below were called



      BEGIN;
      SELECT * FROM foo;
      INSERT INTO foo(name) VALUES ('bar');
      BEGIN; <- The point of interest
      END;


      Would PostgreSQL discard the second BEGIN or would a commit be implicitly decided on and then run the BEGIN END block at the end as a separate transaction?










      share|improve this question














      What behaviour would PostgreSQL display if for example the script below were called



      BEGIN;
      SELECT * FROM foo;
      INSERT INTO foo(name) VALUES ('bar');
      BEGIN; <- The point of interest
      END;


      Would PostgreSQL discard the second BEGIN or would a commit be implicitly decided on and then run the BEGIN END block at the end as a separate transaction?







      postgresql postgresql-9.3 transaction






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Oct 24 '14 at 9:35









      AlexAlex

      60115




      60115






















          4 Answers
          4






          active

          oldest

          votes


















          10














          What you would need is a so called "autonomous transaction" (a feature provided by oracle). At this point this is not possible in PostgreSQL yet.
          However, you can use SAVEPOINTs:



          BEGIN;
          INSERT ...
          SAVEPOINT a;
          some error;
          ROLLBACK TO SAVEPOINT a;
          COMMIT;


          It is not entirely an autonomous transaction - but, it allows you get "every transaction" right. You can use it to achieve the thing you expect from autonomous transactions.



          Otherwise there are no other reasonable solution at this point.






          share|improve this answer

































            11














            You could try it yourself:




            WARNING: there is already a transaction in progress




            It starts no new (sub)transaction as nested transactions are not implemented in PostgreSQL. (You may do some magic in a pl/pgsql function, for example, that mimics that behaviour, though.)



            With PostgreSQL 11, one could think the new real stored procedures and their ability to handle transactions would make nested transactions possible. However, according to the documentation, this is not the case:




            In procedures invoked by the CALL command as well as in anonymous code blocks (DO command), it is possible to end transactions using the commands COMMIT and ROLLBACK. A new transaction is started automatically after a transaction is ended using these commands, so there is no separate START TRANSACTION command.







            share|improve this answer

































              6














              PostgreSQL does not support sub-transactions, but the SAVEPOINT feature can effectively answer your need. Quoting from the documentation for Advanced access layer to PG via promises by Vitaly Tomilov on GitHub:




              PostgreSQL doesn't have proper support for nested transactions, it only supports partial rollbacks via savepoints inside transactions. The difference between the two techniques is huge, as explained further.



              Proper support for nested transactions means that the result of a successful sub-transaction isn't rolled back when its parent transaction is rolled back. But with PostgreSQL save-points, if you roll-back the top-level transaction, the result of all inner save-points is also rolled back.




              Savepoints can be used for partial rollbacks to an earlier point inside an active transaction. For example, to establish a savepoint and later undo the effects of all commands executed after it was established:



              BEGIN;
              INSERT INTO table1 VALUES (1);
              SAVEPOINT my_savepoint;
              INSERT INTO table1 VALUES (2);
              ROLLBACK TO SAVEPOINT my_savepoint;
              INSERT INTO table1 VALUES (3);
              COMMIT;


              The above transaction will insert the values 1 and 3, but not 2. See the SAVEPOINT documentation for more information.






              share|improve this answer

































                0














                For Postgresql 9.5 or newer you can use dynamic background workers provided by pg_background extension. It creates autonomous transaction. Please, refer the github page of the extension. The sollution is better then db_link. There is a complete guide on Autonomous transaction support in PostgreSQL






                share|improve this answer























                  Your Answer








                  StackExchange.ready(function() {
                  var channelOptions = {
                  tags: "".split(" "),
                  id: "182"
                  };
                  initTagRenderer("".split(" "), "".split(" "), channelOptions);

                  StackExchange.using("externalEditor", function() {
                  // Have to fire editor after snippets, if snippets enabled
                  if (StackExchange.settings.snippets.snippetsEnabled) {
                  StackExchange.using("snippets", function() {
                  createEditor();
                  });
                  }
                  else {
                  createEditor();
                  }
                  });

                  function createEditor() {
                  StackExchange.prepareEditor({
                  heartbeatType: 'answer',
                  autoActivateHeartbeat: false,
                  convertImagesToLinks: false,
                  noModals: true,
                  showLowRepImageUploadWarning: true,
                  reputationToPostImages: null,
                  bindNavPrevention: true,
                  postfix: "",
                  imageUploader: {
                  brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                  contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                  allowUrls: true
                  },
                  onDemand: true,
                  discardSelector: ".discard-answer"
                  ,immediatelyShowMarkdownHelp:true
                  });


                  }
                  });














                  draft saved

                  draft discarded


















                  StackExchange.ready(
                  function () {
                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f81011%2ftransactions-within-a-transaction%23new-answer', 'question_page');
                  }
                  );

                  Post as a guest















                  Required, but never shown

























                  4 Answers
                  4






                  active

                  oldest

                  votes








                  4 Answers
                  4






                  active

                  oldest

                  votes









                  active

                  oldest

                  votes






                  active

                  oldest

                  votes









                  10














                  What you would need is a so called "autonomous transaction" (a feature provided by oracle). At this point this is not possible in PostgreSQL yet.
                  However, you can use SAVEPOINTs:



                  BEGIN;
                  INSERT ...
                  SAVEPOINT a;
                  some error;
                  ROLLBACK TO SAVEPOINT a;
                  COMMIT;


                  It is not entirely an autonomous transaction - but, it allows you get "every transaction" right. You can use it to achieve the thing you expect from autonomous transactions.



                  Otherwise there are no other reasonable solution at this point.






                  share|improve this answer






























                    10














                    What you would need is a so called "autonomous transaction" (a feature provided by oracle). At this point this is not possible in PostgreSQL yet.
                    However, you can use SAVEPOINTs:



                    BEGIN;
                    INSERT ...
                    SAVEPOINT a;
                    some error;
                    ROLLBACK TO SAVEPOINT a;
                    COMMIT;


                    It is not entirely an autonomous transaction - but, it allows you get "every transaction" right. You can use it to achieve the thing you expect from autonomous transactions.



                    Otherwise there are no other reasonable solution at this point.






                    share|improve this answer




























                      10












                      10








                      10







                      What you would need is a so called "autonomous transaction" (a feature provided by oracle). At this point this is not possible in PostgreSQL yet.
                      However, you can use SAVEPOINTs:



                      BEGIN;
                      INSERT ...
                      SAVEPOINT a;
                      some error;
                      ROLLBACK TO SAVEPOINT a;
                      COMMIT;


                      It is not entirely an autonomous transaction - but, it allows you get "every transaction" right. You can use it to achieve the thing you expect from autonomous transactions.



                      Otherwise there are no other reasonable solution at this point.






                      share|improve this answer















                      What you would need is a so called "autonomous transaction" (a feature provided by oracle). At this point this is not possible in PostgreSQL yet.
                      However, you can use SAVEPOINTs:



                      BEGIN;
                      INSERT ...
                      SAVEPOINT a;
                      some error;
                      ROLLBACK TO SAVEPOINT a;
                      COMMIT;


                      It is not entirely an autonomous transaction - but, it allows you get "every transaction" right. You can use it to achieve the thing you expect from autonomous transactions.



                      Otherwise there are no other reasonable solution at this point.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited May 9 '16 at 9:59









                      Amir Ali Akbari

                      17317




                      17317










                      answered Oct 27 '14 at 11:46









                      Hans-Jürgen SchönigHans-Jürgen Schönig

                      95658




                      95658

























                          11














                          You could try it yourself:




                          WARNING: there is already a transaction in progress




                          It starts no new (sub)transaction as nested transactions are not implemented in PostgreSQL. (You may do some magic in a pl/pgsql function, for example, that mimics that behaviour, though.)



                          With PostgreSQL 11, one could think the new real stored procedures and their ability to handle transactions would make nested transactions possible. However, according to the documentation, this is not the case:




                          In procedures invoked by the CALL command as well as in anonymous code blocks (DO command), it is possible to end transactions using the commands COMMIT and ROLLBACK. A new transaction is started automatically after a transaction is ended using these commands, so there is no separate START TRANSACTION command.







                          share|improve this answer






























                            11














                            You could try it yourself:




                            WARNING: there is already a transaction in progress




                            It starts no new (sub)transaction as nested transactions are not implemented in PostgreSQL. (You may do some magic in a pl/pgsql function, for example, that mimics that behaviour, though.)



                            With PostgreSQL 11, one could think the new real stored procedures and their ability to handle transactions would make nested transactions possible. However, according to the documentation, this is not the case:




                            In procedures invoked by the CALL command as well as in anonymous code blocks (DO command), it is possible to end transactions using the commands COMMIT and ROLLBACK. A new transaction is started automatically after a transaction is ended using these commands, so there is no separate START TRANSACTION command.







                            share|improve this answer




























                              11












                              11








                              11







                              You could try it yourself:




                              WARNING: there is already a transaction in progress




                              It starts no new (sub)transaction as nested transactions are not implemented in PostgreSQL. (You may do some magic in a pl/pgsql function, for example, that mimics that behaviour, though.)



                              With PostgreSQL 11, one could think the new real stored procedures and their ability to handle transactions would make nested transactions possible. However, according to the documentation, this is not the case:




                              In procedures invoked by the CALL command as well as in anonymous code blocks (DO command), it is possible to end transactions using the commands COMMIT and ROLLBACK. A new transaction is started automatically after a transaction is ended using these commands, so there is no separate START TRANSACTION command.







                              share|improve this answer















                              You could try it yourself:




                              WARNING: there is already a transaction in progress




                              It starts no new (sub)transaction as nested transactions are not implemented in PostgreSQL. (You may do some magic in a pl/pgsql function, for example, that mimics that behaviour, though.)



                              With PostgreSQL 11, one could think the new real stored procedures and their ability to handle transactions would make nested transactions possible. However, according to the documentation, this is not the case:




                              In procedures invoked by the CALL command as well as in anonymous code blocks (DO command), it is possible to end transactions using the commands COMMIT and ROLLBACK. A new transaction is started automatically after a transaction is ended using these commands, so there is no separate START TRANSACTION command.








                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited 6 mins ago

























                              answered Oct 24 '14 at 13:49









                              dezsodezso

                              21.6k105793




                              21.6k105793























                                  6














                                  PostgreSQL does not support sub-transactions, but the SAVEPOINT feature can effectively answer your need. Quoting from the documentation for Advanced access layer to PG via promises by Vitaly Tomilov on GitHub:




                                  PostgreSQL doesn't have proper support for nested transactions, it only supports partial rollbacks via savepoints inside transactions. The difference between the two techniques is huge, as explained further.



                                  Proper support for nested transactions means that the result of a successful sub-transaction isn't rolled back when its parent transaction is rolled back. But with PostgreSQL save-points, if you roll-back the top-level transaction, the result of all inner save-points is also rolled back.




                                  Savepoints can be used for partial rollbacks to an earlier point inside an active transaction. For example, to establish a savepoint and later undo the effects of all commands executed after it was established:



                                  BEGIN;
                                  INSERT INTO table1 VALUES (1);
                                  SAVEPOINT my_savepoint;
                                  INSERT INTO table1 VALUES (2);
                                  ROLLBACK TO SAVEPOINT my_savepoint;
                                  INSERT INTO table1 VALUES (3);
                                  COMMIT;


                                  The above transaction will insert the values 1 and 3, but not 2. See the SAVEPOINT documentation for more information.






                                  share|improve this answer






























                                    6














                                    PostgreSQL does not support sub-transactions, but the SAVEPOINT feature can effectively answer your need. Quoting from the documentation for Advanced access layer to PG via promises by Vitaly Tomilov on GitHub:




                                    PostgreSQL doesn't have proper support for nested transactions, it only supports partial rollbacks via savepoints inside transactions. The difference between the two techniques is huge, as explained further.



                                    Proper support for nested transactions means that the result of a successful sub-transaction isn't rolled back when its parent transaction is rolled back. But with PostgreSQL save-points, if you roll-back the top-level transaction, the result of all inner save-points is also rolled back.




                                    Savepoints can be used for partial rollbacks to an earlier point inside an active transaction. For example, to establish a savepoint and later undo the effects of all commands executed after it was established:



                                    BEGIN;
                                    INSERT INTO table1 VALUES (1);
                                    SAVEPOINT my_savepoint;
                                    INSERT INTO table1 VALUES (2);
                                    ROLLBACK TO SAVEPOINT my_savepoint;
                                    INSERT INTO table1 VALUES (3);
                                    COMMIT;


                                    The above transaction will insert the values 1 and 3, but not 2. See the SAVEPOINT documentation for more information.






                                    share|improve this answer




























                                      6












                                      6








                                      6







                                      PostgreSQL does not support sub-transactions, but the SAVEPOINT feature can effectively answer your need. Quoting from the documentation for Advanced access layer to PG via promises by Vitaly Tomilov on GitHub:




                                      PostgreSQL doesn't have proper support for nested transactions, it only supports partial rollbacks via savepoints inside transactions. The difference between the two techniques is huge, as explained further.



                                      Proper support for nested transactions means that the result of a successful sub-transaction isn't rolled back when its parent transaction is rolled back. But with PostgreSQL save-points, if you roll-back the top-level transaction, the result of all inner save-points is also rolled back.




                                      Savepoints can be used for partial rollbacks to an earlier point inside an active transaction. For example, to establish a savepoint and later undo the effects of all commands executed after it was established:



                                      BEGIN;
                                      INSERT INTO table1 VALUES (1);
                                      SAVEPOINT my_savepoint;
                                      INSERT INTO table1 VALUES (2);
                                      ROLLBACK TO SAVEPOINT my_savepoint;
                                      INSERT INTO table1 VALUES (3);
                                      COMMIT;


                                      The above transaction will insert the values 1 and 3, but not 2. See the SAVEPOINT documentation for more information.






                                      share|improve this answer















                                      PostgreSQL does not support sub-transactions, but the SAVEPOINT feature can effectively answer your need. Quoting from the documentation for Advanced access layer to PG via promises by Vitaly Tomilov on GitHub:




                                      PostgreSQL doesn't have proper support for nested transactions, it only supports partial rollbacks via savepoints inside transactions. The difference between the two techniques is huge, as explained further.



                                      Proper support for nested transactions means that the result of a successful sub-transaction isn't rolled back when its parent transaction is rolled back. But with PostgreSQL save-points, if you roll-back the top-level transaction, the result of all inner save-points is also rolled back.




                                      Savepoints can be used for partial rollbacks to an earlier point inside an active transaction. For example, to establish a savepoint and later undo the effects of all commands executed after it was established:



                                      BEGIN;
                                      INSERT INTO table1 VALUES (1);
                                      SAVEPOINT my_savepoint;
                                      INSERT INTO table1 VALUES (2);
                                      ROLLBACK TO SAVEPOINT my_savepoint;
                                      INSERT INTO table1 VALUES (3);
                                      COMMIT;


                                      The above transaction will insert the values 1 and 3, but not 2. See the SAVEPOINT documentation for more information.







                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited May 10 '16 at 4:35









                                      Paul White

                                      49.3k14260414




                                      49.3k14260414










                                      answered May 9 '16 at 9:43









                                      Amir Ali AkbariAmir Ali Akbari

                                      17317




                                      17317























                                          0














                                          For Postgresql 9.5 or newer you can use dynamic background workers provided by pg_background extension. It creates autonomous transaction. Please, refer the github page of the extension. The sollution is better then db_link. There is a complete guide on Autonomous transaction support in PostgreSQL






                                          share|improve this answer




























                                            0














                                            For Postgresql 9.5 or newer you can use dynamic background workers provided by pg_background extension. It creates autonomous transaction. Please, refer the github page of the extension. The sollution is better then db_link. There is a complete guide on Autonomous transaction support in PostgreSQL






                                            share|improve this answer


























                                              0












                                              0








                                              0







                                              For Postgresql 9.5 or newer you can use dynamic background workers provided by pg_background extension. It creates autonomous transaction. Please, refer the github page of the extension. The sollution is better then db_link. There is a complete guide on Autonomous transaction support in PostgreSQL






                                              share|improve this answer













                                              For Postgresql 9.5 or newer you can use dynamic background workers provided by pg_background extension. It creates autonomous transaction. Please, refer the github page of the extension. The sollution is better then db_link. There is a complete guide on Autonomous transaction support in PostgreSQL







                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered Mar 3 '17 at 23:19









                                              shcherbakshcherbak

                                              1358




                                              1358






























                                                  draft saved

                                                  draft discarded




















































                                                  Thanks for contributing an answer to Database Administrators Stack Exchange!


                                                  • Please be sure to answer the question. Provide details and share your research!

                                                  But avoid



                                                  • Asking for help, clarification, or responding to other answers.

                                                  • Making statements based on opinion; back them up with references or personal experience.


                                                  To learn more, see our tips on writing great answers.




                                                  draft saved


                                                  draft discarded














                                                  StackExchange.ready(
                                                  function () {
                                                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f81011%2ftransactions-within-a-transaction%23new-answer', 'question_page');
                                                  }
                                                  );

                                                  Post as a guest















                                                  Required, but never shown





















































                                                  Required, but never shown














                                                  Required, but never shown












                                                  Required, but never shown







                                                  Required, but never shown

































                                                  Required, but never shown














                                                  Required, but never shown












                                                  Required, but never shown







                                                  Required, but never shown







                                                  Popular posts from this blog

                                                  Liste der Baudenkmale in Friedland (Mecklenburg)

                                                  Single-Malt-Whisky

                                                  Czorneboh