Browse Source

clientv3: don't retry txns that may modify the store

Anthony Romano 10 years ago
parent
commit
b6a08a97e2
3 changed files with 13 additions and 1 deletions
  1. 1 1
      clientv3/kv.go
  2. 4 0
      clientv3/op.go
  3. 8 0
      clientv3/txn.go

+ 1 - 1
clientv3/kv.go

@@ -185,7 +185,7 @@ func (kv *kv) do(op Op) (*pb.ResponseUnion, error) {
 		}
 
 		// do not retry on modifications
-		if op.t != tRange {
+		if op.isWrite() {
 			go kv.switchRemote(err)
 			return nil, err
 		}

+ 4 - 0
clientv3/op.go

@@ -64,6 +64,10 @@ func (op Op) toRequestUnion() *pb.RequestUnion {
 	}
 }
 
+func (op Op) isWrite() bool {
+	return op.t != tRange
+}
+
 func OpRange(key, end string, limit, rev int64, sort *SortOption) Op {
 	return Op{
 		t:   tRange,

+ 8 - 0
clientv3/txn.go

@@ -58,6 +58,8 @@ type txn struct {
 	cthen bool
 	celse bool
 
+	isWrite bool
+
 	cmps []*pb.Compare
 
 	sus []*pb.RequestUnion
@@ -101,6 +103,7 @@ func (txn *txn) Then(ops ...Op) Txn {
 	txn.cthen = true
 
 	for _, op := range ops {
+		txn.isWrite = txn.isWrite || op.isWrite()
 		txn.sus = append(txn.sus, op.toRequestUnion())
 	}
 
@@ -118,6 +121,7 @@ func (txn *txn) Else(ops ...Op) Txn {
 	txn.celse = true
 
 	for _, op := range ops {
+		txn.isWrite = txn.isWrite || op.isWrite()
 		txn.fas = append(txn.fas, op.toRequestUnion())
 	}
 
@@ -137,6 +141,10 @@ func (txn *txn) Commit() (*TxnResponse, error) {
 			return (*TxnResponse)(resp), nil
 		}
 
+		if txn.isWrite {
+			return nil, err
+		}
+
 		if isRPCError(err) {
 			return nil, err
 		}