Uploaded image for project: 'Go Driver'
  1. Go Driver
  2. GODRIVER-2001

Session.WithTransaction method endless loop

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 1.5.3
    • Affects Version/s: None
    • Component/s: None
    • None
    • Not Needed

      version: 1.5.2

      I use a context with a short timeout, and find WithTransaction method will be stuck in a endless loop

      Here is my code:

      client, err := mongo.NewClient()
      if err != nil {
         return
      }
      
      err = client.Connect(context.Background())
      if err != nil {
         return
      }
      s, err := client.StartSession()
      if err != nil {
         return
      }
      _, err = s.WithTransaction(context.Background(), func(ctx mongo.SessionContext) (interface{}, error) {
         c, cancel := context.WithTimeout(ctx, time.Nanosecond)
         defer cancel()
      
         // infinite loop
         _, err = client.Database("xxx").
            Collection("xxx").
            InsertOne(c, nil)
         if err != nil {
            return nil, err
         }
      
         return nil, nil
      })
      if err != nil {
         return
      }
      

      The InsertOne method will return the following error:

       

       

      connection(xxxx) failed to write: context deadline exceeded
      

      The error has TransientTransactionError and NetworkError label, so it make WithTransaction method stuck in an infinite loop

       

       

      for {
         err = s.StartTransaction(opts...)
         if err != nil {
            return nil, err
         }
      
         res, err := fn(NewSessionContext(ctx, s))
         if err != nil {
            if s.clientSession.TransactionRunning() {
               // Wrap the user-provided Context in a new one that behaves like context.Background() for deadlines and
               // cancellations, but forwards Value requests to the original one.
               _ = s.AbortTransaction(internal.NewBackgroundContext(ctx))
            }
      
            select {
            case <-timeout.C:
               return nil, err
            default:
            }
      
            if errorHasLabel(err, driver.TransientTransactionError) {
               continue
            }
            return res, err
         }
      }
      

       

       

            Assignee:
            benji.rewis@mongodb.com Benji Rewis (Inactive)
            Reporter:
            zjm448172381@gmail.com 峻铭 张
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: