@@ -650,8 +650,8 @@ pgfdw_xact_callback(XactEvent event, void *arg)
650
650
{
651
651
switch (event )
652
652
{
653
- case XACT_EVENT_PARALLEL_COMMIT :
654
- case XACT_EVENT_COMMIT :
653
+ case XACT_EVENT_PARALLEL_PRE_COMMIT :
654
+ case XACT_EVENT_PRE_COMMIT :
655
655
{
656
656
csn_t maxCSN = 0 ;
657
657
@@ -668,160 +668,134 @@ pgfdw_xact_callback(XactEvent event, void *arg)
668
668
{
669
669
RunDtmCommand (psprintf ("ROLLBACK PREPARED '%d.%d'" ,
670
670
MyProcPid , currentLocalTransactionId ));
671
- }
672
- break ;
671
+ ereport (ERROR ,
672
+ (errcode (ERRCODE_TRANSACTION_ROLLBACK ),
673
+ errmsg ("transaction was aborted at one of the shards" )));
674
+ break ;
675
+ }
676
+ return ;
673
677
}
674
- case XACT_EVENT_ABORT :
675
- RunDtmCommand ("ROLLBACK" );
676
- break ;
677
- case XACT_EVENT_PRE_PREPARE :
678
- ereport (ERROR ,
679
- (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
680
- errmsg ("cannot prepare a transaction that modified remote tables" )));
681
- break ;
682
678
default :
683
- break ;
679
+ break ;
684
680
}
685
-
686
- currentGlobalTransactionId = 0 ;
687
-
688
- hash_seq_init (& scan , ConnectionHash );
689
- while ((entry = (ConnCacheEntry * ) hash_seq_search (& scan )))
690
- {
691
- /* Ignore cache entry if no open connection right now */
692
- if (entry -> conn == NULL )
693
- continue ;
694
- /* Reset state to show we're out of a transaction */
695
- entry -> xact_depth = 0 ;
696
-
697
- /*
698
- * If the connection isn't in a good idle state, discard it to
699
- * recover. Next GetConnection will open a new connection.
700
- */
701
- if (PQstatus (entry -> conn ) != CONNECTION_OK ||
702
- PQtransactionStatus (entry -> conn ) != PQTRANS_IDLE )
703
- {
704
- elog (DEBUG3 , "discarding connection %p, conn status=%d, trans status=%d" , entry -> conn , PQstatus (entry -> conn ), PQtransactionStatus (entry -> conn ));
705
- PQfinish (entry -> conn );
706
- entry -> conn = NULL ;
707
- }
708
- }
709
- } else {
710
- /*
711
- * Scan all connection cache entries to find open remote transactions, and
712
- * close them.
713
- */
714
- hash_seq_init (& scan , ConnectionHash );
715
- while ((entry = (ConnCacheEntry * ) hash_seq_search (& scan )))
716
- {
717
- PGresult * res ;
681
+ }
682
+ /*
683
+ * Scan all connection cache entries to find open remote transactions, and
684
+ * close them.
685
+ */
686
+ hash_seq_init (& scan , ConnectionHash );
687
+ while ((entry = (ConnCacheEntry * ) hash_seq_search (& scan )))
688
+ {
689
+ PGresult * res ;
718
690
719
- /* Ignore cache entry if no open connection right now */
720
- if (entry -> conn == NULL )
721
- continue ;
691
+ /* Ignore cache entry if no open connection right now */
692
+ if (entry -> conn == NULL )
693
+ continue ;
722
694
723
- /* If it has an open remote transaction, try to close it */
724
- if (entry -> xact_depth > 0 )
725
- {
726
- elog (DEBUG3 , "closing remote transaction on connection %p event %d" ,
727
- entry -> conn , event );
695
+ /* If it has an open remote transaction, try to close it */
696
+ if (entry -> xact_depth > 0 )
697
+ {
698
+ elog (DEBUG3 , "closing remote transaction on connection %p event %d" ,
699
+ entry -> conn , event );
728
700
729
- switch (event )
730
- {
731
- case XACT_EVENT_PARALLEL_PRE_COMMIT :
732
- case XACT_EVENT_PRE_COMMIT :
733
- /* Commit all remote transactions during pre-commit */
734
- do_sql_send_command (entry -> conn , "COMMIT TRANSACTION" );
735
- continue ;
701
+ switch (event )
702
+ {
703
+ case XACT_EVENT_PARALLEL_PRE_COMMIT :
704
+ case XACT_EVENT_PRE_COMMIT :
705
+ /* Commit all remote transactions during pre-commit */
706
+ do_sql_send_command (entry -> conn , "COMMIT TRANSACTION" );
707
+ continue ;
736
708
737
- case XACT_EVENT_PRE_PREPARE :
738
- /*
739
- * We disallow remote transactions that modified anything,
740
- * since it's not very reasonable to hold them open until
741
- * the prepared transaction is committed. For the moment,
742
- * throw error unconditionally; later we might allow
743
- * read-only cases. Note that the error will cause us to
744
- * come right back here with event == XACT_EVENT_ABORT, so
745
- * we'll clean up the connection state at that point.
746
- */
747
- ereport (ERROR ,
748
- (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
749
- errmsg ("cannot prepare a transaction that modified remote tables" )));
750
- break ;
751
-
752
- case XACT_EVENT_PARALLEL_COMMIT :
753
- case XACT_EVENT_COMMIT :
754
- case XACT_EVENT_PREPARE :
755
- do_sql_wait_command (entry -> conn , "COMMIT TRANSACTION" );
756
- /*
757
- * If there were any errors in subtransactions, and we
758
- * made prepared statements, do a DEALLOCATE ALL to make
759
- * sure we get rid of all prepared statements. This is
760
- * annoying and not terribly bulletproof, but it's
761
- * probably not worth trying harder.
762
- *
763
- * DEALLOCATE ALL only exists in 8.3 and later, so this
764
- * constrains how old a server postgres_fdw can
765
- * communicate with. We intentionally ignore errors in
766
- * the DEALLOCATE, so that we can hobble along to some
767
- * extent with older servers (leaking prepared statements
768
- * as we go; but we don't really support update operations
769
- * pre-8.3 anyway).
770
- */
709
+ case XACT_EVENT_PRE_PREPARE :
710
+ /*
711
+ * We disallow remote transactions that modified anything,
712
+ * since it's not very reasonable to hold them open until
713
+ * the prepared transaction is committed. For the moment,
714
+ * throw error unconditionally; later we might allow
715
+ * read-only cases. Note that the error will cause us to
716
+ * come right back here with event == XACT_EVENT_ABORT, so
717
+ * we'll clean up the connection state at that point.
718
+ */
719
+ ereport (ERROR ,
720
+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
721
+ errmsg ("cannot prepare a transaction that modified remote tables" )));
722
+ break ;
723
+
724
+ case XACT_EVENT_PARALLEL_COMMIT :
725
+ case XACT_EVENT_COMMIT :
726
+ case XACT_EVENT_PREPARE :
727
+ if (!currentGlobalTransactionId )
728
+ {
729
+ do_sql_wait_command (entry -> conn , "COMMIT TRANSACTION" );
730
+ }
731
+ /*
732
+ * If there were any errors in subtransactions, and we
733
+ * made prepared statements, do a DEALLOCATE ALL to make
734
+ * sure we get rid of all prepared statements. This is
735
+ * annoying and not terribly bulletproof, but it's
736
+ * probably not worth trying harder.
737
+ *
738
+ * DEALLOCATE ALL only exists in 8.3 and later, so this
739
+ * constrains how old a server postgres_fdw can
740
+ * communicate with. We intentionally ignore errors in
741
+ * the DEALLOCATE, so that we can hobble along to some
742
+ * extent with older servers (leaking prepared statements
743
+ * as we go; but we don't really support update operations
744
+ * pre-8.3 anyway).
745
+ */
746
+ if (entry -> have_prep_stmt && entry -> have_error )
747
+ {
748
+ res = PQexec (entry -> conn , "DEALLOCATE ALL" );
749
+ PQclear (res );
750
+ }
751
+ entry -> have_prep_stmt = false;
752
+ entry -> have_error = false;
753
+ break ;
754
+
755
+ case XACT_EVENT_PARALLEL_ABORT :
756
+ case XACT_EVENT_ABORT :
757
+ /* Assume we might have lost track of prepared statements */
758
+ entry -> have_error = true;
759
+ /* If we're aborting, abort all remote transactions too */
760
+ res = PQexec (entry -> conn , "ABORT TRANSACTION" );
761
+ /* Note: can't throw ERROR, it would be infinite loop */
762
+ if (PQresultStatus (res ) != PGRES_COMMAND_OK )
763
+ pgfdw_report_error (WARNING , res , entry -> conn , true,
764
+ "ABORT TRANSACTION" );
765
+ else
766
+ {
767
+ PQclear (res );
768
+ /* As above, make sure to clear any prepared stmts */
771
769
if (entry -> have_prep_stmt && entry -> have_error )
772
770
{
773
771
res = PQexec (entry -> conn , "DEALLOCATE ALL" );
774
772
PQclear (res );
775
773
}
776
774
entry -> have_prep_stmt = false;
777
775
entry -> have_error = false;
778
- break ;
779
-
780
- case XACT_EVENT_PARALLEL_ABORT :
781
- case XACT_EVENT_ABORT :
782
- /* Assume we might have lost track of prepared statements */
783
- entry -> have_error = true;
784
- /* If we're aborting, abort all remote transactions too */
785
- res = PQexec (entry -> conn , "ABORT TRANSACTION" );
786
- /* Note: can't throw ERROR, it would be infinite loop */
787
- if (PQresultStatus (res ) != PGRES_COMMAND_OK )
788
- pgfdw_report_error (WARNING , res , entry -> conn , true,
789
- "ABORT TRANSACTION" );
790
- else
791
- {
792
- PQclear (res );
793
- /* As above, make sure to clear any prepared stmts */
794
- if (entry -> have_prep_stmt && entry -> have_error )
795
- {
796
- res = PQexec (entry -> conn , "DEALLOCATE ALL" );
797
- PQclear (res );
798
- }
799
- entry -> have_prep_stmt = false;
800
- entry -> have_error = false;
801
- }
802
- break ;
803
-
804
- case XACT_EVENT_START :
805
- case XACT_EVENT_ABORT_PREPARED :
806
- case XACT_EVENT_COMMIT_PREPARED :
807
- break ;
808
- }
809
- }
810
- /* Reset state to show we're out of a transaction */
811
- entry -> xact_depth = 0 ;
812
-
813
- /*
814
- * If the connection isn't in a good idle state, discard it to
815
- * recover. Next GetConnection will open a new connection.
816
- */
817
- if (PQstatus (entry -> conn ) != CONNECTION_OK ||
818
- PQtransactionStatus (entry -> conn ) != PQTRANS_IDLE )
819
- {
820
- elog (DEBUG3 , "discarding connection %p, conn status=%d, trans status=%d" , entry -> conn , PQstatus (entry -> conn ), PQtransactionStatus (entry -> conn ));
821
- PQfinish (entry -> conn );
822
- entry -> conn = NULL ;
776
+ }
777
+ break ;
778
+
779
+ case XACT_EVENT_START :
780
+ case XACT_EVENT_ABORT_PREPARED :
781
+ case XACT_EVENT_COMMIT_PREPARED :
782
+ break ;
823
783
}
824
784
}
785
+ /* Reset state to show we're out of a transaction */
786
+ entry -> xact_depth = 0 ;
787
+
788
+ /*
789
+ * If the connection isn't in a good idle state, discard it to
790
+ * recover. Next GetConnection will open a new connection.
791
+ */
792
+ if (PQstatus (entry -> conn ) != CONNECTION_OK ||
793
+ PQtransactionStatus (entry -> conn ) != PQTRANS_IDLE )
794
+ {
795
+ elog (WARNING , "discarding connection %p, conn status=%d, trans status=%d" , entry -> conn , PQstatus (entry -> conn ), PQtransactionStatus (entry -> conn ));
796
+ PQfinish (entry -> conn );
797
+ entry -> conn = NULL ;
798
+ }
825
799
}
826
800
if (event != XACT_EVENT_PARALLEL_PRE_COMMIT && event != XACT_EVENT_PRE_COMMIT ) {
827
801
/*
@@ -833,6 +807,8 @@ pgfdw_xact_callback(XactEvent event, void *arg)
833
807
834
808
/* Also reset cursor numbering for next transaction */
835
809
cursor_number = 0 ;
810
+
811
+ currentGlobalTransactionId = 0 ;
836
812
}
837
813
}
838
814
0 commit comments