Appengine的数据存储游标永远不变

I am trying to update a lot of records, to which cannot be done within the one minute max request time given, so I need to use a datastore.Cursor, but for some reason the returned cursor is always the same. So each redirect is done with the same cursor value, resulting in the the same 20 database updates being performed each time.

Any ideas to why things aren't working like I would like?

http.HandleFunc("/fix", func(w, http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)
    fixUser(c, w, r, "/fix", func() error { 
       // do the fix here
       return nil
    })
})

func fixUser(ctx context.Context, w http.ResponseWriter, r *http.Request, path string, fn func(user *User) error) {
    q := datastore.NewQuery("users")
    c := r.URL.Query().Get("c")
    if len(c) > 0 {
        cursor, err := datastore.DecodeCursor(c)
        if err != nil {
            w.WriteHeader(http.StatusInternalServerError)
            w.Write([]byte(err.Error()))
            return
        }
        q.Start(cursor)
    }

    iter := q.Run(ctx)
    var cr datastore.Cursor
    for i := 0; i < 20; i++ {
        var u User
        key, err := iter.Next(&u)
        if err == datastore.Done {
            return
        }
        if err != nil {
            panic(err.Error())
        }
        cr, _ = iter.Cursor()
        log.Debugf(ctx, "Cursor: %v", cr)   // always the same value
        u.Key = key
        fn(&u)
    }

    pathWithCursor := fmt.Sprintf("%s?c=%s", path, cr.String())
    http.Redirect(w, r, pathWithCursor, 301)
}

I looked at some of my own cursor code and compared it against yours. The main difference I see is that I use q = q.Start(cursor) rather than q.start(cursor). This should fix your problem since your query will now be updated to reflect the position specified by the cursor. Without storing your query back into the q variable, your query will not update.