code: func (e *SelectLockExec) Next(ctx context.Context, req *chunk.RecordBatch) error {
  	req.GrowAndReset(e.maxChunkSize)
  	err := e.children[0].Next(ctx, req)
  	if err != nil {
  		return err
  	}
  	// If there's no handle or it's not a `SELECT FOR UPDATE` statement.
  	if len(e.Schema().TblID2Handle) == 0 || e.Lock != ast.SelectLockForUpdate {
  		return nil
  	}
  	txn, err := e.ctx.Txn(true)
  	if err != nil {
  		return err
  	}
  	keys := make([]kv.Key, 0, req.NumRows())
  	iter := chunk.NewIterator4Chunk(req.Chunk)
  	for id, cols := range e.Schema().TblID2Handle {
  		for _, col := range cols {
  			keys = keys[:0]
  			for row := iter.Begin(); row != iter.End(); row = iter.Next() {
  				keys = append(keys, tablecodec.EncodeRowKeyWithHandle(id, row.GetInt64(col.Index)))
  			}
  			err = txn.LockKeys(keys...)
  			if err != nil {
  				return err
  			}
  		}
  	}
  	return nil
  }
docs: // Next implements the Executor Next interface.