@@ -28,6 +28,30 @@ type TransactionResponse struct {
2828 CommitIndex uint64
2929}
3030
31+ // applyAndBarrier submits a log entry, waits for it to be applied, and
32+ // surfaces both Raft transport errors and errors returned from FSM.Apply.
33+ // HashiCorp Raft delivers FSM errors via ApplyFuture.Response(), not Error(),
34+ // so we must inspect the response to avoid silently treating failed writes as
35+ // successes.
36+ func applyAndBarrier (r * raft.Raft , b []byte ) (uint64 , error ) {
37+ af := r .Apply (b , time .Second )
38+ if err := af .Error (); err != nil {
39+ return 0 , errors .WithStack (err )
40+ }
41+
42+ if resp := af .Response (); resp != nil {
43+ if err , ok := resp .(error ); ok && err != nil {
44+ return 0 , errors .WithStack (err )
45+ }
46+ }
47+
48+ if f := r .Barrier (time .Second ); f .Error () != nil {
49+ return 0 , errors .WithStack (f .Error ())
50+ }
51+
52+ return af .Index (), nil
53+ }
54+
3155func (t * TransactionManager ) Commit (reqs []* pb.Request ) (* TransactionResponse , error ) {
3256 commitIndex , err := func () (uint64 , error ) {
3357 commitIndex := uint64 (0 )
@@ -37,15 +61,11 @@ func (t *TransactionManager) Commit(reqs []*pb.Request) (*TransactionResponse, e
3761 return 0 , errors .WithStack (err )
3862 }
3963
40- af := t .raft .Apply (b , time .Second )
41- if af .Error () != nil {
42- return 0 , errors .WithStack (af .Error ())
43- }
44- f := t .raft .Barrier (time .Second )
45- if f .Error () != nil {
46- return 0 , errors .WithStack (f .Error ())
64+ idx , err := applyAndBarrier (t .raft , b )
65+ if err != nil {
66+ return 0 , err
4767 }
48- commitIndex = af . Index ()
68+ commitIndex = idx
4969 }
5070
5171 return commitIndex , nil
@@ -83,15 +103,11 @@ func (t *TransactionManager) Abort(reqs []*pb.Request) (*TransactionResponse, er
83103 return nil , errors .WithStack (err )
84104 }
85105
86- af := t .raft .Apply (b , time .Second )
87- if af .Error () != nil {
88- return nil , errors .WithStack (af .Error ())
89- }
90- f := t .raft .Barrier (time .Second )
91- if f .Error () != nil {
92- return nil , errors .WithStack (f .Error ())
106+ idx , err := applyAndBarrier (t .raft , b )
107+ if err != nil {
108+ return nil , err
93109 }
94- commitIndex = af . Index ()
110+ commitIndex = idx
95111 }
96112
97113 return & TransactionResponse {
0 commit comments