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

Fix txnNumber addition for retryable writes



    • Type: Bug
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Fixed
    • Affects Version/s: 1.4.0, 1.3.7
    • Fix Version/s: 1.4.2
    • Component/s: API
    • Security Level: Public
    • Labels:
    • Environment:
      Linux, Mongo 3.X/4.X
    • Backwards Compatibility:
      Fully Compatible



      Standalone servers support sessions, but the driver errors if a retryable write is done in an explicit session because we add a txnNumber field. We should only add the txnNumber for replica sets and sharded clusters.



      Coming from the mgo community driver, I have discovered sessions in the mongo-go-driver rely on 'server sessions'. As an application developer, I am forced to now know what mongo topology the end user is running, with no apparent way to do so, in order to detect if server sessions can be used or not.

      It would be preferable if sessions become a no-op if a single mongo is used instead of getting what will appear to most users as an unrelated error due to the advent of multi-document transactions:

      "Transaction numbers are only allowed on a replica set member or mongos"

      I only discovered this was an issue in a library I have created after migrating to mongo-driver once I had control over the session/context via v1.4.0. This is also somewhat related to mongo version/feature detection for enabling transactions: GODRIVER-1732


      This localhost repro shows the failure when running on a single mongo:

      package main
      import (
         log "github.com/sirupsen/logrus"
      type Bar struct {
         Name   string
         Type   string
         Rating int
      func main() {
         ctx := context.Background()
         client, err := mongo.Connect(ctx)
         if err != nil {
            log.WithError(err).Fatal("Unable to build mongo connection!")
         sess, _ := client.StartSession()
         err = mongo.WithSession(ctx, sess, func(ctx mongo.SessionContext) error {
            // check connection works as mongo-go lazily connects.
            err = client.Ping(ctx, nil)
            if err != nil {
               log.WithError(err).Error("Unable to connect to mongo! Have you configured your connection properly?")
               return err
            bar := Bar{
               Name:   "Moro Bar",
               Type:   "Chocolate",
               Rating: 10,
            res, err := client.Database("foo").Collection("bar").InsertOne(ctx, bar)
            if err != nil {
               log.WithError(err).Fatal("unable to insert a foobar")
               return err
            log.WithField("id", res.InsertedID).Info("inserted bar")
            return nil
         if err != nil {
            log.WithError(err).Fatal("unable to insert a fooMorobar")



      The mongo-driver paradigm will throw people off  migrating from mgo.  At the minimum it should be documented that mongo sessions require a replica set.




            isabella.siu Isabella Siu
            matt.hartstonge@gmail.com Matt Hartstonge
            1 Vote for this issue
            3 Start watching this issue