@@ -3814,7 +3814,7 @@ FlagRWConflict(SERIALIZABLEXACT *reader, SERIALIZABLEXACT *writer)
3814
3814
SetRWConflict (reader , writer );
3815
3815
}
3816
3816
3817
- /*
3817
+ /*----------------------------------------------------------------------------
3818
3818
* We are about to add a RW-edge to the dependency graph - check that we don't
3819
3819
* introduce a dangerous structure by doing so, and abort one of the
3820
3820
* transactions if so.
@@ -3823,13 +3823,14 @@ FlagRWConflict(SERIALIZABLEXACT *reader, SERIALIZABLEXACT *writer)
3823
3823
* in the dependency graph:
3824
3824
*
3825
3825
* Tin ------> Tpivot ------> Tout
3826
- * rw rw
3826
+ * rw rw
3827
3827
*
3828
3828
* Furthermore, Tout must commit first.
3829
3829
*
3830
3830
* One more optimization is that if Tin is declared READ ONLY (or commits
3831
3831
* without writing), we can only have a problem if Tout committed before Tin
3832
3832
* acquired its snapshot.
3833
+ *----------------------------------------------------------------------------
3833
3834
*/
3834
3835
static void
3835
3836
OnConflict_CheckForSerializationFailure (const SERIALIZABLEXACT * reader ,
@@ -3842,32 +3843,34 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader,
3842
3843
3843
3844
failure = false;
3844
3845
3845
- /*
3846
+ /*------------------------------------------------------------------------
3846
3847
* Check for already-committed writer with rw-conflict out flagged
3847
3848
* (conflict-flag on W means that T2 committed before W):
3848
3849
*
3849
3850
* R ------> W ------> T2
3850
- * rw rw
3851
+ * rw rw
3851
3852
*
3852
3853
* That is a dangerous structure, so we must abort. (Since the writer
3853
3854
* has already committed, we must be the reader)
3855
+ *------------------------------------------------------------------------
3854
3856
*/
3855
3857
if (SxactIsCommitted (writer )
3856
3858
&& (SxactHasConflictOut (writer ) || SxactHasSummaryConflictOut (writer )))
3857
3859
failure = true;
3858
3860
3859
- /*
3861
+ /*------------------------------------------------------------------------
3860
3862
* Check whether the writer has become a pivot with an out-conflict
3861
3863
* committed transaction (T2), and T2 committed first:
3862
3864
*
3863
3865
* R ------> W ------> T2
3864
- * rw rw
3866
+ * rw rw
3865
3867
*
3866
3868
* Because T2 must've committed first, there is no anomaly if:
3867
3869
* - the reader committed before T2
3868
3870
* - the writer committed before T2
3869
3871
* - the reader is a READ ONLY transaction and the reader was concurrent
3870
3872
* with T2 (= reader acquired its snapshot before T2 committed)
3873
+ *------------------------------------------------------------------------
3871
3874
*/
3872
3875
if (!failure )
3873
3876
{
@@ -3891,7 +3894,7 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader,
3891
3894
&& (!SxactIsCommitted (writer )
3892
3895
|| t2 -> commitSeqNo <= writer -> commitSeqNo )
3893
3896
&& (!SxactIsReadOnly (reader )
3894
- || t2 -> commitSeqNo <= reader -> SeqNo .lastCommitBeforeSnapshot ))
3897
+ || t2 -> commitSeqNo <= reader -> SeqNo .lastCommitBeforeSnapshot ))
3895
3898
{
3896
3899
failure = true;
3897
3900
break ;
@@ -3903,16 +3906,17 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader,
3903
3906
}
3904
3907
}
3905
3908
3906
- /*
3909
+ /*------------------------------------------------------------------------
3907
3910
* Check whether the reader has become a pivot with a committed writer:
3908
3911
*
3909
3912
* T0 ------> R ------> W
3910
- * rw rw
3913
+ * rw rw
3911
3914
*
3912
3915
* Because W must've committed first for an anomaly to occur, there is no
3913
3916
* anomaly if:
3914
3917
* - T0 committed before the writer
3915
3918
* - T0 is READ ONLY, and overlaps the writer
3919
+ *------------------------------------------------------------------------
3916
3920
*/
3917
3921
if (!failure && SxactIsCommitted (writer ) && !SxactIsReadOnly (reader ))
3918
3922
{
@@ -3934,7 +3938,7 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader,
3934
3938
&& (!SxactIsCommitted (t0 )
3935
3939
|| t0 -> commitSeqNo >= writer -> commitSeqNo )
3936
3940
&& (!SxactIsReadOnly (t0 )
3937
- || t0 -> SeqNo .lastCommitBeforeSnapshot >= writer -> commitSeqNo ))
3941
+ || t0 -> SeqNo .lastCommitBeforeSnapshot >= writer -> commitSeqNo ))
3938
3942
{
3939
3943
failure = true;
3940
3944
break ;
@@ -3950,8 +3954,8 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader,
3950
3954
{
3951
3955
/*
3952
3956
* We have to kill a transaction to avoid a possible anomaly from
3953
- * occurring. If the writer is us, we can just ereport() to cause
3954
- * a transaction abort. Otherwise we flag the writer for termination,
3957
+ * occurring. If the writer is us, we can just ereport() to cause a
3958
+ * transaction abort. Otherwise we flag the writer for termination,
3955
3959
* causing it to abort when it tries to commit. However, if the writer
3956
3960
* is a prepared transaction, already prepared, we can't abort it
3957
3961
* anymore, so we have to kill the reader instead.
@@ -3962,7 +3966,7 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader,
3962
3966
ereport (ERROR ,
3963
3967
(errcode (ERRCODE_T_R_SERIALIZATION_FAILURE ),
3964
3968
errmsg ("could not serialize access due to read/write dependencies among transactions" ),
3965
- errdetail ("Cancelled on identification as a pivot, during write." ),
3969
+ errdetail ("Cancelled on identification as a pivot, during write." ),
3966
3970
errhint ("The transaction might succeed if retried." )));
3967
3971
}
3968
3972
else if (SxactIsPrepared (writer ))
0 commit comments