1 /*-------------------------------------------------------------------------
2  * remote_transaction.h
3  *
4  * Copyright (c) Citus Data, Inc.
5  *
6  *-------------------------------------------------------------------------
7  */
8 
9 
10 #ifndef REMOTE_TRANSACTION_H
11 #define REMOTE_TRANSACTION_H
12 
13 
14 #include "libpq-fe.h"
15 #include "nodes/pg_list.h"
16 #include "lib/ilist.h"
17 
18 
19 /* forward declare, to avoid recursive includes */
20 struct MultiConnection;
21 
22 /*
23  * Enum that defines different remote transaction states, of a single remote
24  * transaction.
25  */
26 typedef enum
27 {
28 	/* no transaction active */
29 	REMOTE_TRANS_NOT_STARTED = 0,
30 
31 	/* transaction start */
32 	REMOTE_TRANS_STARTING,
33 	REMOTE_TRANS_STARTED,
34 
35 	/* command execution */
36 	REMOTE_TRANS_SENT_BEGIN,
37 	REMOTE_TRANS_SENT_COMMAND,
38 	REMOTE_TRANS_FETCHING_RESULTS,
39 	REMOTE_TRANS_CLEARING_RESULTS,
40 
41 	/* 2pc prepare */
42 	REMOTE_TRANS_PREPARING,
43 	REMOTE_TRANS_PREPARED,
44 
45 	/* transaction abort */
46 	REMOTE_TRANS_1PC_ABORTING,
47 	REMOTE_TRANS_2PC_ABORTING,
48 	REMOTE_TRANS_ABORTED,
49 
50 	/* transaction commit */
51 	REMOTE_TRANS_1PC_COMMITTING,
52 	REMOTE_TRANS_2PC_COMMITTING,
53 	REMOTE_TRANS_COMMITTED
54 } RemoteTransactionState;
55 
56 
57 /*
58  * Transaction state associated associated with a single MultiConnection.
59  */
60 typedef struct RemoteTransaction
61 {
62 	/* what state is the remote side transaction in */
63 	RemoteTransactionState transactionState;
64 
65 	/* failures on this connection should abort entire coordinated transaction */
66 	bool transactionCritical;
67 
68 	/* failed in current transaction */
69 	bool transactionFailed;
70 
71 	/*
72 	 * Id of last savepoint that successfully began before transaction failure.
73 	 * Since savepoint ids are assigned incrementally, rolling back to any savepoint
74 	 * with id equal to or less than this id recovers the transaction from failures.
75 	 */
76 	SubTransactionId lastSuccessfulSubXact;
77 
78 	/* Id of last savepoint queued before first query of transaction */
79 	SubTransactionId lastQueuedSubXact;
80 
81 	/* waiting for the result of a recovering ROLLBACK TO SAVEPOINT command */
82 	bool transactionRecovering;
83 
84 	/* 2PC transaction name currently associated with connection */
85 	char preparedName[NAMEDATALEN];
86 
87 	/* set when BEGIN is sent over the connection */
88 	bool beginSent;
89 } RemoteTransaction;
90 
91 
92 /* utility functions for dealing with remote transactions */
93 extern bool ParsePreparedTransactionName(char *preparedTransactionName, int32 *groupId,
94 										 int *procId, uint64 *transactionNumber,
95 										 uint32 *connectionNumber);
96 
97 /* change an individual remote transaction's state */
98 extern void StartRemoteTransactionBegin(struct MultiConnection *connection);
99 extern void FinishRemoteTransactionBegin(struct MultiConnection *connection);
100 extern void RemoteTransactionBegin(struct MultiConnection *connection);
101 extern void RemoteTransactionListBegin(List *connectionList);
102 
103 extern void StartRemoteTransactionPrepare(struct MultiConnection *connection);
104 extern void FinishRemoteTransactionPrepare(struct MultiConnection *connection);
105 
106 extern void StartRemoteTransactionCommit(struct MultiConnection *connection);
107 extern void FinishRemoteTransactionCommit(struct MultiConnection *connection);
108 extern void RemoteTransactionCommit(struct MultiConnection *connection);
109 
110 extern void StartRemoteTransactionAbort(struct MultiConnection *connection);
111 extern void FinishRemoteTransactionAbort(struct MultiConnection *connection);
112 extern void RemoteTransactionAbort(struct MultiConnection *connection);
113 
114 /* start transaction if necessary */
115 extern void RemoteTransactionBeginIfNecessary(struct MultiConnection *connection);
116 extern void RemoteTransactionsBeginIfNecessary(List *connectionList);
117 
118 /* other public functionality */
119 extern void HandleRemoteTransactionConnectionError(struct MultiConnection *connection,
120 												   bool raiseError);
121 extern void HandleRemoteTransactionResultError(struct MultiConnection *connection,
122 											   PGresult *result, bool raiseErrors);
123 extern void MarkRemoteTransactionFailed(struct MultiConnection *connection,
124 										bool allowErrorPromotion);
125 extern void MarkRemoteTransactionCritical(struct MultiConnection *connection);
126 
127 
128 /*
129  * The following functions should all only be called by connection /
130  * transaction managment code.
131  */
132 
133 extern void CloseRemoteTransaction(struct MultiConnection *connection);
134 extern void ResetRemoteTransaction(struct MultiConnection *connection);
135 
136 /* perform handling for all in-progress transactions */
137 extern void CoordinatedRemoteTransactionsPrepare(void);
138 extern void CoordinatedRemoteTransactionsCommit(void);
139 extern void CoordinatedRemoteTransactionsAbort(void);
140 extern void CheckRemoteTransactionsHealth(void);
141 
142 /* remote savepoint commands */
143 extern void CoordinatedRemoteTransactionsSavepointBegin(SubTransactionId subId);
144 extern void CoordinatedRemoteTransactionsSavepointRelease(SubTransactionId subId);
145 extern void CoordinatedRemoteTransactionsSavepointRollback(SubTransactionId subId);
146 
147 #endif /* REMOTE_TRANSACTION_H */
148