# File lib/mongo/session.rb, line 263
    def add_txn_opts!(command, read)
      command.tap do |c|
        # The read preference should be added for all read operations.
        if read && txn_read_pref = txn_read_preference
          Mongo::Lint.validate_underscore_read_preference(txn_read_pref)
          txn_read_pref = txn_read_pref.dup
          txn_read_pref[:mode] = txn_read_pref[:mode].to_s.gsub(/(_\w)/) { |match| match[1].upcase }
          Mongo::Lint.validate_camel_case_read_preference(txn_read_pref)
          c['$readPreference'] = txn_read_pref
        end

        # 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 ] = rc
          end
        end

        # We need to send the read concern level as a string rather than a symbol.
        if c[:readConcern] && c[:readConcern][:level]
          c[:readConcern][:level] = c[:readConcern][:level].to_s
        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
      end
    end