Method: Mongo::Session#add_txn_opts!

Defined in:
lib/mongo/session.rb

#add_txn_opts!(command, read, context) ⇒ Hash, BSON::Document

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Add the transactions options if applicable.

Examples:

session.add_txn_opts!(cmd)

Returns:

  • (Hash, BSON::Document)

    The command document.

Since:

  • 2.6.0



946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
# File 'lib/mongo/session.rb', line 946

def add_txn_opts!(command, read, context)
  command.tap do |c|
    # The read concern should be added to any command that starts a transaction.
    if starting_transaction?
      # https://jira.mongodb.org/browse/SPEC-1161: transaction's
      # read concern overrides collection/database/client read concerns,
      # even if transaction's read concern is not set.
      # Read concern here is the one sent to the server and may
      # include afterClusterTime.
      if rc = c[:readConcern]
        rc = rc.dup
        rc.delete(:level)
      end
      if txn_read_concern
        if rc
          rc.update(txn_read_concern)
        else
          rc = txn_read_concern.dup
        end
      end
      if rc.nil? || rc.empty?
        c.delete(:readConcern)
      else
        c[:readConcern ] = Options::Mapper.transform_values_to_strings(rc)
      end
    end

    # We need to send the read concern level as a string rather than a symbol.
    if c[:readConcern]
      c[:readConcern] = Options::Mapper.transform_values_to_strings(c[:readConcern])
    end

    if c[:commitTransaction]
      if max_time_ms = txn_options[:max_commit_time_ms]
        c[:maxTimeMS] = max_time_ms
      end
    end

    # The write concern should be added to any abortTransaction or commitTransaction command.
    if (c[:abortTransaction] || c[:commitTransaction])
      if @already_committed
        wc = BSON::Document.new(c[:writeConcern] || txn_write_concern || {})
        wc.merge!(w: :majority)
        wc[:wtimeout] ||= 10000
        c[:writeConcern] = wc
      elsif txn_write_concern
        c[:writeConcern] ||= txn_write_concern
      end
    end

    # A non-numeric write concern w value needs to be sent as a string rather than a symbol.
    if c[:writeConcern] && c[:writeConcern][:w] && c[:writeConcern][:w].is_a?(Symbol)
      c[:writeConcern][:w] = c[:writeConcern][:w].to_s
    end

    # Ignore wtimeout if csot
    if context&.csot?
      c[:writeConcern]&.delete(:wtimeout)
    end

    # We must not send an empty (server default) write concern.
    c.delete(:writeConcern) if c[:writeConcern]&.empty?
  end
end