func (ts *txnSender) Send(ctx context.Context, ba roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error) { // Send call through wrapped sender. ba.Txn = &ts.Proto if ts.UserPriority > 0 { ba.UserPriority = ts.UserPriority } ba.SetNewRequest() br, pErr := ts.wrapped.Send(ctx, ba) if br != nil && br.Error != nil { panic(roachpb.ErrorUnexpectedlySet(ts.wrapped, br)) } // Only successful requests can carry an updated Txn in their response // header. Any error (e.g. a restart) can have a Txn attached to them as // well; those update our local state in the same way for the next attempt. // The exception is if our transaction was aborted and needs to restart // from scratch, in which case we do just that. if pErr == nil { ts.Proto.Update(br.Txn) return br, nil } else if _, ok := pErr.GetDetail().(*roachpb.TransactionAbortedError); ok { // On Abort, reset the transaction so we start anew on restart. ts.Proto = roachpb.Transaction{ Name: ts.Proto.Name, Isolation: ts.Proto.Isolation, } // Acts as a minimum priority on restart. if pErr.GetTxn() != nil { ts.Proto.Priority = pErr.GetTxn().Priority } } else if pErr.TransactionRestart != roachpb.TransactionRestart_ABORT { ts.Proto.Update(pErr.GetTxn()) } return nil, pErr }
// send runs the specified calls synchronously in a single batch and returns // any errors. Returns (nil, nil) for an empty batch. func (db *DB) send(ba roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error) { if len(ba.Requests) == 0 { return nil, nil } if ba.ReadConsistency == roachpb.INCONSISTENT { for _, ru := range ba.Requests { req := ru.GetInner() if req.Method() != roachpb.Get && req.Method() != roachpb.Scan && req.Method() != roachpb.ReverseScan { return nil, roachpb.NewErrorf("method %s not allowed with INCONSISTENT batch", req.Method) } } } if db.ctx.UserPriority != 1 { ba.UserPriority = db.ctx.UserPriority } tracing.AnnotateTrace() br, pErr := db.sender.Send(context.TODO(), ba) if pErr != nil { if log.V(1) { log.Infof("failed batch: %s", pErr) } return nil, pErr } return br, nil }
// send runs the specified calls synchronously in a single batch and returns // any errors. Returns a nil response for empty input (no requests). func (db *DB) send(maxScanResults int64, readConsistency roachpb.ReadConsistencyType, reqs ...roachpb.Request) (*roachpb.BatchResponse, *roachpb.Error) { if len(reqs) == 0 { return nil, nil } if readConsistency == roachpb.INCONSISTENT { for _, req := range reqs { if req.Method() != roachpb.Get && req.Method() != roachpb.Scan && req.Method() != roachpb.ReverseScan { return nil, roachpb.NewErrorf("method %s not allowed with INCONSISTENT batch", req.Method) } } } ba := roachpb.BatchRequest{} ba.Add(reqs...) ba.MaxScanResults = maxScanResults if db.userPriority != 1 { ba.UserPriority = db.userPriority } ba.ReadConsistency = readConsistency tracing.AnnotateTrace() br, pErr := db.sender.Send(context.TODO(), ba) if pErr != nil { if log.V(1) { log.Infof("failed batch: %s", pErr) } return nil, pErr } return br, nil }
// send runs the specified calls synchronously in a single batch and returns // any errors. Returns a nil response for empty input (no requests). func (db *DB) send(maxScanResults int64, reqs ...roachpb.Request) ( *roachpb.BatchResponse, *roachpb.Error) { if len(reqs) == 0 { return nil, nil } ba := roachpb.BatchRequest{} ba.Add(reqs...) ba.MaxScanResults = maxScanResults if db.userPriority != 1 { ba.UserPriority = db.userPriority } tracing.AnnotateTrace() br, pErr := db.sender.Send(context.TODO(), ba) if pErr != nil { if log.V(1) { log.Infof("failed batch: %s", pErr) } return nil, pErr } return br, nil }
// Send updates the transaction on error. Depending on the error type, the // transaction might be replaced by a new one. func (ts *txnSender) Send(ctx context.Context, ba roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error) { // Send call through wrapped sender. ba.Txn = &ts.Proto // For testing purposes, ts.UserPriority can be a negative value (see // MakePriority). if ts.UserPriority != 0 { ba.UserPriority = ts.UserPriority } br, pErr := ts.wrapped.Send(ts.Context, ba) if br != nil && br.Error != nil { panic(roachpb.ErrorUnexpectedlySet(ts.wrapped, br)) } if br != nil { for _, encSp := range br.CollectedSpans { var newSp basictracer.RawSpan if err := tracing.DecodeRawSpan(encSp, &newSp); err != nil { return nil, roachpb.NewError(err) } ts.CollectedSpans = append(ts.CollectedSpans, newSp) } } // Only successful requests can carry an updated Txn in their response // header. Any error (e.g. a restart) can have a Txn attached to them as // well; those update our local state in the same way for the next attempt. // The exception is if our transaction was aborted and needs to restart // from scratch, in which case we do just that. if pErr == nil { ts.Proto.Update(br.Txn) return br, nil } else if _, ok := pErr.GetDetail().(*roachpb.TransactionAbortedError); ok { // On Abort, reset the transaction so we start anew on restart. ts.Proto = roachpb.Transaction{ TxnMeta: roachpb.TxnMeta{ Isolation: ts.Proto.Isolation, }, Name: ts.Proto.Name, } // Acts as a minimum priority on restart. if pErr.GetTxn() != nil { ts.Proto.Priority = pErr.GetTxn().Priority } } else if pErr.TransactionRestart != roachpb.TransactionRestart_NONE { ts.Proto.Update(pErr.GetTxn()) } return nil, pErr }
// send runs the specified calls synchronously in a single batch and returns // any errors. Returns a nil response for empty input (no requests). func (db *DB) send(reqs ...roachpb.Request) (*roachpb.BatchResponse, *roachpb.Error) { if len(reqs) == 0 { return nil, nil } ba := roachpb.BatchRequest{} ba.Add(reqs...) if ba.UserPriority == 0 && db.userPriority != 1 { ba.UserPriority = db.userPriority } br, pErr := db.sender.Send(context.TODO(), ba) if pErr != nil { if log.V(1) { log.Infof("failed batch: %s", pErr) } return nil, pErr } return br, nil }
// send runs the specified calls synchronously in a single batch and // returns any errors. func (db *DB) send(reqs ...roachpb.Request) (*roachpb.BatchResponse, *roachpb.Error) { if len(reqs) == 0 { return &roachpb.BatchResponse{}, nil } ba := roachpb.BatchRequest{} ba.Add(reqs...) if ba.UserPriority == nil && db.userPriority != 0 { ba.UserPriority = proto.Int32(db.userPriority) } resetClientCmdID(&ba) br, pErr := db.sender.Send(context.TODO(), ba) if pErr != nil { if log.V(1) { log.Infof("failed batch: %s", pErr) } return nil, pErr } return br, nil }