@@ -453,7 +453,7 @@ static void DtmPrepareTransaction(DtmCurrentTrans* x)
453
453
ts -> status = TRANSACTION_STATUS_UNKNOWN ;
454
454
ts -> csn = dtm_get_csn ();
455
455
ts -> procno = MyProc -> pgprocno ;
456
- ts -> nVotes = 1 ; /* I voted myself */
456
+ ts -> nVotes = 1 ; /* My own voice */
457
457
for (i = 0 ; i < MMNodes ; i ++ ) {
458
458
ts -> xids [i ] = InvalidTransactionId ;
459
459
}
@@ -479,7 +479,8 @@ static XidStatus
479
479
DtmCommitTransaction (TransactionId xid , int nsubxids , TransactionId * subxids )
480
480
{
481
481
DtmTransState * ts ;
482
- csn_t csn ;
482
+ csn_t localCSN ;
483
+ csn_t globalCSN ;
483
484
int i ;
484
485
XidStatus status ;
485
486
@@ -489,44 +490,45 @@ DtmCommitTransaction(TransactionId xid, int nsubxids, TransactionId *subxids)
489
490
490
491
/* now transaction is in doubt state */
491
492
ts -> status = TRANSACTION_STATUS_IN_PROGRESS ;
492
- csn = dtm_get_csn ();
493
- if (csn > ts -> csn ) {
494
- ts -> csn = csn ;
495
- }
493
+ localCSN = dtm_get_csn ();
494
+ ts -> csn = localCSN ;
496
495
DtmTransactionListAppend (ts );
497
496
DtmAddSubtransactions (ts , subxids , nsubxids );
498
497
499
498
MMVoteForTransaction (ts ); /* wait until transaction at all nodes are prepared */
500
- csn = ts -> csn ;
501
- if (csn != INVALID_CSN ) {
502
- dtm_sync (csn );
499
+ globalCSN = ts -> csn ;
500
+ Assert (globalCSN >= localCSN );
501
+
502
+ if (globalCSN != INVALID_CSN ) {
503
+ dtm_sync (globalCSN );
503
504
status = TRANSACTION_STATUS_COMMITTED ;
504
505
} else {
506
+ ts -> csn = globalCSN = localCSN ;
505
507
status = TRANSACTION_STATUS_ABORTED ;
506
508
}
507
509
ts -> status = status ;
508
510
for (i = 0 ; i < nsubxids ; i ++ ) {
509
511
ts = ts -> next ;
510
512
ts -> status = status ;
511
- ts -> csn = csn ;
513
+ ts -> csn = globalCSN ;
512
514
}
513
515
LWLockRelease (dtm -> hashLock );
514
516
return status ;
515
517
}
516
518
517
519
static void
518
- DtmAbortTransaction (TransactionId xid , int nsubxids , TransactionId * subxids )
520
+ DtmFinishTransaction (TransactionId xid , int nsubxids , TransactionId * subxids , XidStatus status )
519
521
{
520
522
int i ;
521
523
DtmTransState * ts ;
522
524
523
525
LWLockAcquire (dtm -> hashLock , LW_EXCLUSIVE );
524
526
ts = hash_search (xid2state , & xid , HASH_FIND , NULL );
525
527
Assert (ts != NULL ); /* should be created by DtmPrepareTransaction */
526
- ts -> status = TRANSACTION_STATUS_ABORTED ;
528
+ ts -> status = status ;
527
529
for (i = 0 ; i < nsubxids ; i ++ ) {
528
530
ts = ts -> next ;
529
- ts -> status = TRANSACTION_STATUS_ABORTED ;
531
+ ts -> status = status ;
530
532
}
531
533
LWLockRelease (dtm -> hashLock );
532
534
}
@@ -539,9 +541,10 @@ DtmSetTransactionStatus(TransactionId xid, int nsubxids, TransactionId *subxids,
539
541
DTM_INFO ("%d: DtmSetTransactionStatus %u = %u\n" , getpid (), xid , status );
540
542
if (dtmTx .isDistributed )
541
543
{
544
+ Assert (xid == dtmTx .xid );
542
545
if (status == TRANSACTION_STATUS_ABORTED || !dtmTx .containsDML )
543
546
{
544
- DtmAbortTransaction (xid , nsubxids , subxids );
547
+ DtmFinishTransaction (xid , nsubxids , subxids , status );
545
548
DTM_INFO ("Abort transaction %d\n" , xid );
546
549
}
547
550
else
@@ -990,12 +993,18 @@ MMPoolConstructor(void)
990
993
static void
991
994
SendCommitMessage (DtmTransState * ts )
992
995
{
996
+ DtmTransState * votingList ;
997
+
993
998
SpinLockAcquire (& dtm -> votingSpinlock );
994
- ts -> nextVoting = dtm -> votingTransactions ;
999
+ votingList = dtm -> votingTransactions ;
1000
+ ts -> nextVoting = votingList ;
995
1001
dtm -> votingTransactions = ts ;
996
1002
SpinLockRelease (& dtm -> votingSpinlock );
997
1003
998
- PGSemaphoreUnlock (& dtm -> votingSemaphore );
1004
+ if (votingList == NULL ) {
1005
+ /* singal semaphreo only once for the whole list */
1006
+ PGSemaphoreUnlock (& dtm -> votingSemaphore );
1007
+ }
999
1008
}
1000
1009
1001
1010
static void
@@ -1011,7 +1020,7 @@ MMVoteForTransaction(DtmTransState* ts)
1011
1020
/* ... and then send notifications to replicas */
1012
1021
SendCommitMessage (ts );
1013
1022
} else {
1014
- /* I am replica: first notify master ... */
1023
+ /* I am replica: first notify coordinator ... */
1015
1024
ts -> nVotes = dtm -> nNodes - 1 ; /* I just need one confirmation from coordinator */
1016
1025
SendCommitMessage (ts );
1017
1026
/* ... and wait response from it */
0 commit comments