code: func (t *Txn) Read(args *structs.TxnReadRequest, reply *structs.TxnReadResponse) error {
  	if done, err := t.srv.forward("Txn.Read", args, args, reply); done {
  		return err
  	}
  	defer metrics.MeasureSince([]string{"txn", "read"}, time.Now())
  
  	// We have to do this ourselves since we are not doing a blocking RPC.
  	t.srv.setQueryMeta(&reply.QueryMeta)
  	if args.RequireConsistent {
  		if err := t.srv.consistentRead(); err != nil {
  			return err
  		}
  	}
  
  	// Run the pre-checks before we perform the read.
  	authorizer, err := t.srv.ResolveToken(args.Token)
  	if err != nil {
  		return err
  	}
  	reply.Errors = t.preCheck(authorizer, args.Ops)
  	if len(reply.Errors) > 0 {
  		return nil
  	}
  
  	// Run the read transaction.
  	state := t.srv.fsm.State()
  	reply.Results, reply.Errors = state.TxnRO(args.Ops)
  	if authorizer != nil {
  		reply.Results = FilterTxnResults(authorizer, reply.Results)
  	}
  	return nil
  }
docs: // Read is used to perform a read-only transaction that doesn't modify the state
  // store. This is much more scalable since it doesn't go through Raft and
  // supports staleness, so this should be preferred if you're just performing
  // reads.