|
246 | 246 |
|
247 | 247 | #define SxactIsCommitted(sxact) (((sxact)->flags & SXACT_FLAG_COMMITTED) != 0)
|
248 | 248 | #define SxactIsPrepared(sxact) (((sxact)->flags & SXACT_FLAG_PREPARED) != 0)
|
| 249 | +#define SxactIsRolledBack(sxact) (((sxact)->flags & SXACT_FLAG_ROLLED_BACK) != 0) |
249 | 250 | #define SxactIsDoomed(sxact) (((sxact)->flags & SXACT_FLAG_DOOMED) != 0)
|
250 | 251 | #define SxactIsReadOnly(sxact) (((sxact)->flags & SXACT_FLAG_READ_ONLY) != 0)
|
251 | 252 | #define SxactHasSummaryConflictIn(sxact) (((sxact)->flags & SXACT_FLAG_SUMMARY_CONFLICT_IN) != 0)
|
@@ -3046,7 +3047,7 @@ SetNewSxactGlobalXmin(void)
|
3046 | 3047 |
|
3047 | 3048 | for (sxact = FirstPredXact(); sxact != NULL; sxact = NextPredXact(sxact))
|
3048 | 3049 | {
|
3049 |
| - if (!SxactIsDoomed(sxact) |
| 3050 | + if (!SxactIsRolledBack(sxact) |
3050 | 3051 | && !SxactIsCommitted(sxact)
|
3051 | 3052 | && sxact != OldCommittedSxact)
|
3052 | 3053 | {
|
@@ -3113,6 +3114,7 @@ ReleasePredicateLocks(const bool isCommit)
|
3113 | 3114 | Assert(!isCommit || SxactIsPrepared(MySerializableXact));
|
3114 | 3115 | Assert(!isCommit || !SxactIsDoomed(MySerializableXact));
|
3115 | 3116 | Assert(!SxactIsCommitted(MySerializableXact));
|
| 3117 | + Assert(!SxactIsRolledBack(MySerializableXact)); |
3116 | 3118 |
|
3117 | 3119 | /* may not be serializable during COMMIT/ROLLBACK PREPARED */
|
3118 | 3120 | if (MySerializableXact->pid != 0)
|
@@ -3151,7 +3153,22 @@ ReleasePredicateLocks(const bool isCommit)
|
3151 | 3153 | MySerializableXact->flags |= SXACT_FLAG_READ_ONLY;
|
3152 | 3154 | }
|
3153 | 3155 | else
|
| 3156 | + { |
| 3157 | + /* |
| 3158 | + * The DOOMED flag indicates that we intend to roll back this |
| 3159 | + * transaction and so it should not cause serialization failures for |
| 3160 | + * other transactions that conflict with it. Note that this flag might |
| 3161 | + * already be set, if another backend marked this transaction for |
| 3162 | + * abort. |
| 3163 | + * |
| 3164 | + * The ROLLED_BACK flag further indicates that ReleasePredicateLocks |
| 3165 | + * has been called, and so the SerializableXact is eligible for |
| 3166 | + * cleanup. This means it should not be considered when calculating |
| 3167 | + * SxactGlobalXmin. |
| 3168 | + */ |
3154 | 3169 | MySerializableXact->flags |= SXACT_FLAG_DOOMED;
|
| 3170 | + MySerializableXact->flags |= SXACT_FLAG_ROLLED_BACK; |
| 3171 | + } |
3155 | 3172 |
|
3156 | 3173 | if (!topLevelIsDeclaredReadOnly)
|
3157 | 3174 | {
|
@@ -3527,7 +3544,7 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
|
3527 | 3544 | nextConflict;
|
3528 | 3545 |
|
3529 | 3546 | Assert(sxact != NULL);
|
3530 |
| - Assert(SxactIsDoomed(sxact) || SxactIsCommitted(sxact)); |
| 3547 | + Assert(SxactIsRolledBack(sxact) || SxactIsCommitted(sxact)); |
3531 | 3548 | Assert(LWLockHeldByMe(SerializableFinishedListLock));
|
3532 | 3549 |
|
3533 | 3550 | /*
|
|
0 commit comments