// maybeBeginTxn begins a new transaction if a txn has been specified // in the request but has a nil ID. The new transaction is initialized // using the name and isolation in the otherwise uninitialized txn. // The Priority, if non-zero is used as a minimum. func (tc *TxnCoordSender) maybeBeginTxn(header *proto.RequestHeader) { if header.Txn != nil { if len(header.Txn.ID) == 0 { newTxn := proto.NewTransaction(header.Txn.Name, keys.KeyAddress(header.Key), header.GetUserPriority(), header.Txn.Isolation, tc.clock.Now(), tc.clock.MaxOffset().Nanoseconds()) // Use existing priority as a minimum. This is used on transaction // aborts to ratchet priority when creating successor transaction. if newTxn.Priority < header.Txn.Priority { newTxn.Priority = header.Txn.Priority } header.Txn = newTxn } } }
// updateForBatch updates the first argument (the header of a request contained // in a batch) from the second one (the batch header), returning an error when // inconsistencies are found. // It is checked that the individual call does not have a User, UserPriority // or Txn set that differs from the batch's. func updateForBatch(aHeader *proto.RequestHeader, bHeader proto.RequestHeader) error { // Disallow transaction, user and priority on individual calls, unless // equal. if aHeader.User != "" && aHeader.User != bHeader.User { return util.Error("conflicting user on call in batch") } if aPrio := aHeader.GetUserPriority(); aPrio != proto.Default_RequestHeader_UserPriority && aPrio != bHeader.GetUserPriority() { return util.Error("conflicting user priority on call in batch") } if aHeader.Txn != nil && !aHeader.Txn.Equal(bHeader.Txn) { return util.Error("conflicting transaction in transactional batch") } aHeader.User = bHeader.User aHeader.UserPriority = bHeader.UserPriority aHeader.Txn = bHeader.Txn return nil }