Clase: Mongo::Session

Hereda:
Objeto
  • Objeto
Mostrar todo
Ampliado por:
Reenviable
Incluye:
ClusterTime::Consumer, Loggable, Retryable
Definido en:
lib/mongo/session.rb,
lib/mongo/session/session_pool.rb,
lib/mongo/session/server_session.rb,
lib/mongo/session/server_session/dirtyable.rb

Overview

Nota:

Los objetos de sesión no son seguros para subprocesos. Una aplicación puede usar una sesión desde un solo hilo o proceso a la vez.

Una sesión lógica que representa un conjunto de operaciones secuenciales ejecutadas por una aplicación que están relacionadas de alguna manera.

Desde:

  • 2.5.0

Definido bajo Namespace

clase: ServerSession, SessionPool

Resumen de constantes colapsar

MISMATCHED_CLUSTER_ERROR_MSG =

Mensaje de error que indica que la sesión fue recuperada de un cliente con un clúster diferente al del cliente a través del cual se está utilizando actualmente.

Desde:

  • 2.5.0

'La configuración del cliente utilizada para crear esta sesión no coincide con aquella ' +
'del cliente propietario de esta operación. Por favor, use esta sesión únicamente para operaciones a través de su padre ' +
'cliente.'
SESSION_ENDED_ERROR_MSG =

Mensaje de error que describe que la sesión no se puede usar porque ya ha terminado.

Desde:

  • 2.5.0

'Esta sesión ha finalizado y no se puede utilizar. Por favor, cree uno nuevo.'
SESSIONS_NOT_SUPPORTED =
Obsoleto.

Mensaje de error que describe que las sesiones no son soportadas por la versión del servidor.

Desde:

  • 2.5.0

'Las sesiones no son compatibles con los servidores conectados.'
NO_TRANSACTION_STATE =

El estado de una sesión en la que la última operación no estaba relacionada con ninguna transacción o aún no se había producido ninguna operación.

Desde:

  • 2.6.0

no transaction
ESTADO_DE_TRANSACCIÓN_INICIAL =

El estado de una sesión en la que un usuario ha iniciado una transacción, pero aún no se han realizado operaciones dentro de la transacción.

Desde:

  • 2.6.0

:starting_transaction
TRANSACTION_IN_PROGRESS_STATE =

El estado de una sesión en la que se ha iniciado una transacción y se ha producido al menos una operación, pero la transacción aún no se ha confirmado ni abortado.

Desde:

  • 2.6.0

:transaction_in_progress
TRANSACTION_COMMITTED_STATE =

El estado de una sesión en la que la última operación ejecutada fue la confirmación de una transacción.

Desde:

  • 2.6.0

:transaction_committed
TRANSACTION_ABORTED_STATE =

El estado de una sesión en la que la última operación ejecutada fue la cancelación de una transacción.

Desde:

  • 2.6.0

:transaction_aborted
UNLABELED_WRITE_CONCERN_CODES =

Esta constante es parte de una API privada. Deberías evitar usar esta constante si es posible, ya que podría ser retirada o cambiada en el futuro.

Desde:

  • 2.5.0

[
  79,  # UnknownReplWriteConcern
  100, # CannotSatisfyWriteConcern,
].freeze

Constantes incluidas desde Loggable

Loggable::PREFIX

Resumen de atributos de la instancia colapsar

Atributos incluidos de ClusterTime::Consumer

#cluster_time

Resumen del método de instancia colapsar

Métodos incluidos de ClusterTime::Consumer

#advance_cluster_time

Métodos incluidos desde Registrable

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger

Métodos incluidos de Retryable

#read_worker, #select_server, #with_overload_retry, #write_worker

Detalles del Constructor

#initialize(server_session, client, options = {}) ⇒ Sesión

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Nota:

Las aplicaciones deben utilizar Client#start_session para iniciar una sesión. Este constructor es solo para uso interno del controlador.

Iniciar una sesión.

Una sesión puede ser explícita o implícita. La vida útil de las sesiones explícitas es gestionada por la aplicación: las aplicaciones crean explícitamente dichas sesiones y las finalizan explícitamente. Las sesiones implícitas son creadas automáticamente por el driver y su duración es gestionada por el driver.

Cuando se crea una sesión implícita, no se puede asociar una sesión de servidor con ella. La sesión del servidor se retirará del pool de sesiones cuando realmente se ejecute una operación que utilice esta sesión. Cuando se crea una sesión explícita, esta debe hacer referencia a una sesión de servidor que ya está asignada.

Parámetros:

  • server_session (SesiónServidor | nil)

    La sesión del servidor con la que se asocia esta sesión. Si la opción :implicit es verdadera, esto debe ser nulo.

  • Cliente (cliente)

    El cliente a través del cual se crea esta sesión.

  • opciones (encriptada) (por defecto: {})

    Las opciones para esta sesión.

Opciones Hash (options):

  • :consistencia_causal (true|false)

    Si se debe habilitar la coherencia causal para esta sesión.

  • :default_timeout_ms (Integer)

    El valor timeoutMS para las siguientes operaciones ejecutadas en la sesión:

    • commitTransaction
    • abortTransaction
    • withTransaction
    • endSession
  • :default_transaction_options (encriptada)

    Opciones que se pasan a start_transaction por defecto; pueden contener cualquiera de las opciones que start_transaction acepte.

  • :implicit (true|false)

    Solo para uso interno de drivers: especifica si la sesión es implícita. Si esto es cierto, server_session será nil. Esto se hace para que la sesión del servidor solo se consulte después de consultar la conexión.

  • read_preference (encriptada)

    El hash de opciones de preferencia de lectura, con las siguientes claves opcionales:

    • :mode -- la preferencia de lectura como string o símbolo; los valores válidos son :primary, :primary_preferred, :secondary, :secondary_preferred y :nearest.
  • snapshot (true | false)

    Configura la sesión para lecturas de snapshot.

Desde:

  • 2.5.0



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# Archivo 'lib/mongo/session.rb', línea 80

def inicializar(server_session, Cliente, opciones = {})
  si opciones[:consistencia_causal] && opciones[snapshot]
    propagar ArgumentError, ':las opciones :causal_consistency y :snapshot no pueden configurarse ambas en una sesión'
  end

  si opciones[:implicit]
    a menos que server_session.nil?
      propagar ArgumentError, "La sesión implícita no puede hacer referencia a la sesión del servidor durante la construcción"
    end
  elsif server_session.nil?
    propagar ArgumentError, 'La sesión explícita debe hacer referencia a la sesión de servidor durante la construcción'
  end

  @server_session = server_session
  opciones = opciones.dup

  # Las sesiones implícitas solo requieren el clúster y las opciones del cliente (nunca ejecutes
  # transacciones), por lo que se debe evitar crear un clon de Mongo::Client para evitar
  # fugas de memoria: utiliza el cliente original directamente en su lugar.
  @client = opciones[:implicit] ? Cliente : Cliente.Usar(Administrador)
  @cluster = @client.clúster
  @options = opciones.dup.freeze
  @cluster_time = nulo
  @state = NO_TRANSACTION_STATE
  @with_transaction_deadline = nulo
  @with_transaction_timeout_ms = nulo
  @inside_with_transaction = false
end

Detalles de atributo de instancias

#clienteCliente (solo lectura)

Devuelve El cliente a través del cual se creó esta sesión.

Devuelve:

  • (cliente)

    El cliente a través del cual se creó esta sesión.

Desde:

  • 2.5.1



117
118
119
# Archivo 'lib/mongo/session.rb', línea 117

def Cliente
  @client
end

#clústerObjeto (solo lectura)

Desde:

  • 2.5.0



119
120
121
# Archivo 'lib/mongo/session.rb', línea 119

def clúster
  @cluster
end

#operation_timeBSON::Timestamp (solo lectura)

Devuelve el operation time más reciente visto para esta sesión.

Devuelve:

  • (BSON::Timestamp)

    El último operation time visto para esta sesión.

Desde:

  • 2.5.0



130
131
132
# Archivo 'lib/mongo/session.rb', línea 130

def tiempo_de_operación
  @operation_time
end

#opcionesHash (solo lectura)

Devuelve las opciones para esta sesión.

Devuelve:

  • (encriptada)

    Las opciones para esta sesión.

Desde:

  • 2.5.0



112
113
114
# Archivo 'lib/mongo/session.rb', línea 112

def opciones
  @options
end

#pinned_connection_global_idEntero | nulo (solo lectura)

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Devuelve El id global de conexión al que está fijada esta sesión, si lo hay.

Devuelve:

  • (Integer | nil)

    El ID global de conexión al que esta sesión está fijada, si corresponde.

Desde:

  • 2.5.0



281
282
283
# Archivo 'lib/mongo/session.rb', línea 281

def pinned_connection_global_id
  @pinned_connection_global_id
end

#pinned_serverServidor | nil (solo lectura)

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Devuelve el servidor (que debería ser un mongos) al que está fijada esta sesión, si la hay.

Devuelve:

  • (Server | nil)

    El servidor (que debe ser un mongos) al que está fijada esta sesión, si existe.

Desde:

  • 2.5.0



275
276
277
# Archivo 'lib/mongo/session.rb', línea 275

def servidor anclado
  @pinned_server
end

#recovery_tokenBSON::Document | nil

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Devuelve el token de recuperación para la transacción fragmentada que se está ejecutando en esta sesión, si es que hay alguna.

Devuelve:

  • (BSON::Document | nil)

    Token de recuperación para la transacción fragmentada que se está ejecutando en esta sesión, si la hubiera.

Desde:

  • 2.5.0



287
288
289
# Archivo 'lib/mongo/session.rb', línea 287

def recovery_token
  @recovery_token
end

#snapshot_timestampObject

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Desde:

  • 2.5.0



1270
1271
1272
# Archivo 'lib/mongo/session.rb', línea 1270

def timestamp_de_captura
  @snapshot_timestamp
end

#con_plazo_para_la_transacciónInteger | nil (sólo lectura)

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Devoluciones: El plazo de entrega para la transacción actual, si la hay.

Devuelve:

  • (Integer | nil)

    La fecha límite para la transacción actual, si existe.

Desde:

  • 2.5.0



1274
1275
1276
# Archivo 'lib/mongo/session.rb', línea 1274

def with_transaction_deadline
  @with_transaction_deadline
end

Detalles del método de instancia

#abort_transaction(options = nil) ⇒ Object

Aborta la transacción activa actualmente sin realizar ningún cambio en la base de datos.

Ejemplos:

Anule la transacción.

session.abort_transaction

Parámetros:

  • opciones (encriptada) (valor por defecto: nil)

    un conjunto personalizable de opciones

Opciones Hash (options):

  • :timeout_ms (Integer)

    El tiempo de espera de la operación en milisegundos. Debe ser un número entero no negativo. Un valor explícito de 0 significa infinito. El valor por defecto no está definido, lo que significa que se hereda del cliente.

Aumenta:

Desde:

  • 2.6.0



803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
# Archivo 'lib/mongo/session.rb', línea 803

def abortar_transacción(opciones = nulo)
  QueryCache.borrar

  check_if_ended!
  check_if_no_transaction!

  si within_states?(ESTADO_DE_TRANSACCIÓN_CONFIRMADA)
    propagar mongo::Error::OperaciónTransacciónInválida.Nuevo(
      mongo::Error::OperaciónTransacciónInválida.cannot_call_after_msg(
        :commitTransaction, abortTransaction
      )
    )
  end

  si within_states?(TRANSACTION_ABORTED_STATE)
    propagar mongo::Error::OperaciónTransacciónInválida.Nuevo(
      mongo::Error::OperaciónTransacciónInválida.cannot_call_twice_msg(abortTransaction)
    )
  end

  opciones ||= {}

  begin
    a menos que ¿iniciando_transacción?
      @aborting_transaction = true
      context = Operación::Context.Nuevo(
        cliente: @client,
        sesión: sí mismo,
        operation_timeouts: operation_timeouts(opciones)
      )
      escribir_con_reintento(txn_options[conformidad_de_lectura],
                       ending_transaction: true, context: context) hacer |Conexión, txn_num, context|
        Operación = Operación::Comando.Nuevo(
          selector: { abortTransaction: 1 },
          db_name: 'admin',
          sesión: sí mismo,
          txn_num: txn_num
        )
        trazador.trace_operation(Operación, context, op_name: 'abortTransaction') hacer
          Operación.execute_with_connection(Conexión, context: context)
        end
      asegurar
        unpin
      end
    end

    # Finaliza el lapso de transacción antes de cambiar el estado
    trazador.finish_transaction_span(sí mismo)
    @state = TRANSACTION_ABORTED_STATE
  rescate mongo::Error::OperaciónTransacciónInválida
    propagar
  rescate mongo::Error
    trazador.finish_transaction_span(sí mismo)
    @state = TRANSACTION_ABORTED_STATE
  rescate Excepción
    trazador.finish_transaction_span(sí mismo)
    @state = TRANSACTION_ABORTED_STATE
    propagar
  asegurar
    @aborting_transaction = false
  end

  # No hay valor de retorno oficial, pero retorna verdadero para que en interactivo
  # utiliza las sugerencias del método que tuvo éxito.
  true
end

#aborting_transaction?true | false

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Devuelve si la sesión está actualmente abortando una transacción.

Devuelve:

  • (true | false)

    Si la sesión está abortando actualmente una transacción.

Desde:

  • 2.5.0



899
900
901
# Archivo 'lib/mongo/session.rb', línea 899

def aborting_transaction?
  !!@aborting_transaction
end

#add_autocommit!(command) ⇒ Hash, BSON::documento

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Agregar el campo de autocommit a un documento de comando si corresponde.

Ejemplos:

session.add_autocommit!(cmd)

Devuelve:

  • (Hash, BSON::Document)

    El documento del comando.

Desde:

  • 2.6.0



985
986
987
988
989
# Archivo 'lib/mongo/session.rb', línea 985

def agregar_autocommit!(Comando)
  Comando.tocar hacer |C|
    C[:autocommit] = false si en_transacción?
  end
end

#add_start_transaction!(comando) ⇒ Hash, BSON::Document

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Agregar el campo startTransaction a un documento de comando si es aplicable.

Ejemplos:

session.add_start_transaction!(cmd)

Devuelve:

  • (Hash, BSON::Document)

    El documento del comando.

Desde:

  • 2.6.0



1000
1001
1002
1003
1004
# Archivo 'lib/mongo/session.rb', línea 1000

def add_start_transaction!(Comando)
  Comando.tocar hacer |C|
    C[:startTransaction] = true si ¿iniciando_transacción?
  end
end

#añadir_txn_num!(command) ⇒ Hash, BSON::documento

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Agrega el número de transacción a un documento de comando si corresponde.

Ejemplos:

session.add_txn_num!(cmd)

Devuelve:

  • (Hash, BSON::Document)

    El documento del comando.

Desde:

  • 2.6.0



1015
1016
1017
1018
1019
# Archivo 'lib/mongo/session.rb', línea 1015

def add_txn_num!(Comando)
  Comando.tocar hacer |C|
    C[Número de transacción] = BSON::Int64.Nuevo(@server_session.txn_num) si en_transacción?
  end
end

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

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Agregue las opciones de transacciones si corresponde.

Ejemplos:

session.add_txn_opts!(cmd)

Devuelve:

  • (Hash, BSON::Document)

    El documento del comando.

Desde:

  • 2.6.0



1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
# Archivo 'lib/mongo/session.rb', línea 1030

def add_txn_opts!(Comando, _read, context)
  Comando.tocar hacer |C|
    # El nivel de consistencia de lectura debe añadirse a cualquier comando que inicie una transacción.
    si ¿iniciando_transacción?
      # https://jira.mongodb.org/browse/SPEC-1161: de transacción
      # la anulación de nivel de consistencia de lectura reemplaza los niveles de consistencia de lectura de la colección, base de datos o cliente,
      # incluso si no se establece el nivel de consistencia de lectura de la transacción.
      # nivel de consistencia de lectura aquí es la enviada al servidor y puede
      # incluir afterClusterTime.
      si rc = C[Preocupación de lectura]
        rc = rc.dup
        rc.borrar(Nivel)
      end
      si txn_read_concern
        si rc
          rc.update(txn_read_concern)
        else
          rc = txn_read_concern.dup
        end
      end
      si rc.nil? || rc.¿vacío?
        C.borrar(Preocupación de lectura)
      else
        C[Preocupación de lectura] = opciones::Mapeador.transform_values_to_strings(rc)
      end
    end

    # Debemos enviar el nivel de consistencia de lectura como un string en lugar de un símbolo.
    C[Preocupación de lectura] = opciones::Mapeador.transform_values_to_strings(C[Preocupación de lectura]) si C[Preocupación de lectura]

    si C[:commitTransaction] && (max_time_ms = txn_options[tiempo_máximo_de_commit_ms])
      C[Tiempo máximo en milisegundos (:maxTimeMS)] = max_time_ms
    end

    # The nivel de confirmación de escritura (write concern) should be added to any abortTransaction or commitTransaction command.
    si C[abortTransaction] || C[:commitTransaction]
      si @already_committed
        wc = BSON::Documento.Nuevo(C[:writeConcern] || txn_write_concern || {})
        wc.¡Actualizar!(w: mayoría)
        wc[:wtimeout] ||= 10_000
        C[:writeConcern] = wc
      elsif txn_write_concern
        C[:writeConcern] ||= txn_write_concern
      end
    end

    # Un valor de nivel de confirmación de escritura (write concern) w no numérico debe enviarse como una string en lugar de un símbolo.
    si C[:writeConcern] && C[:writeConcern][:w] && C[:writeConcern][:w].is_a?(Símbolo)
      C[:writeConcern][:w] = C[:writeConcern][:w].to_s
    end

    # Ignore wtimeout if csot
    C[:writeConcern]&.borrar(:wtimeout) si context&.csot?

    # No debemos enviar un nivel de confirmación de escritura (write concern) vacío (por defecto del servidor).
    C.borrar(:writeConcern) si C[:writeConcern] && C[:writeConcern].¿vacío?
  end
end

#advance_operation_time(new_operation_time) ⇒ BSON::Timestamp

Avanza el operation time en caché para esta sesión.

Ejemplos:

Avance el operation time.

session.advance_operation_time(timestamp)

Parámetros:

  • new_operation_time (BSON::Timestamp)

    La nueva hora de la operación.

Devuelve:

  • (BSON::Timestamp)

    El max operation time, considerando las horas actuales y las nuevas.

Desde:

  • 2.5.0



1209
1210
1211
1212
1213
1214
1215
# Archivo 'lib/mongo/session.rb', línea 1209

def advance_operation_time(new_operation_time)
  @operation_time = si @operation_time
                      [ @operation_time, new_operation_time ].máximo
                    else
                      new_operation_time
                    end
end

#commit_transaction(opciones = nil) ⇒ objeto

Confirma la transacción activa actual en la sesión.

Ejemplos:

Confirma la transacción.

session.commit_transaction

Parámetros:

  • opciones (encriptada) (valor por defecto: nil)

    un conjunto personalizable de opciones

Opciones Hash (options):

  • conformidad_de_lectura (nil | WriteConcern::Base)

    La nivel de confirmación de escritura (write concern) a usar para esta operación.

  • :timeout_ms (Integer)

    El tiempo de espera de la operación en milisegundos. Debe ser un número entero no negativo. Un valor explícito de 0 significa infinito. El valor por defecto no está definido, lo que significa que se hereda del cliente.

Aumenta:

Desde:

  • 2.6.0



717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
# Archivo 'lib/mongo/session.rb', línea 717

def commit_transaction(opciones = nulo)
  QueryCache.borrar
  check_if_ended!
  check_if_no_transaction!

  si within_states?(TRANSACTION_ABORTED_STATE)
    propagar mongo::Error::OperaciónTransacciónInválida.Nuevo(
      mongo::Error::OperaciónTransacciónInválida.cannot_call_after_msg(
        abortTransaction, :commitTransaction
      )
    )
  end

  opciones ||= {}

  begin
    # Si se llama a commitTransaction dos veces, necesitamos ejecutar el mismo commit
    # operación de nuevo, así que revertimos la sesión al estado anterior.
    si within_states?(ESTADO_DE_TRANSACCIÓN_CONFIRMADA)
      @state = @last_commit_skipped ? STARTING_TRANSACTION_STATE : TRANSACTION_IN_PROGRESS_STATE
      @already_committed = true
    end

    si ¿iniciando_transacción?
      @last_commit_skipped = true
    else
      @last_commit_skipped = false
      @commit_transaction = true

      write_concern = opciones[conformidad_de_lectura] || txn_options[conformidad_de_lectura]
      write_concern = Nivel de confirmación de escritura (write concern).Obtener(write_concern) si write_concern && !write_concern.is_a?(Nivel de confirmación de escritura (write concern)::Base)

      context = Operación::Context.Nuevo(
        cliente: @client,
        sesión: sí mismo,
        operation_timeouts: operation_timeouts(opciones)
      )
      escribir_con_reintento(write_concern, ending_transaction: true,
                                      context: context) hacer |Conexión, txn_num, context|
        si context.¿volver a intentarlo? && !context.overload_only_retry?
          si write_concern
            wco = write_concern.opciones.fusionar(w: mayoría)
            wco[:wtimeout] ||= 10_000
            write_concern = Nivel de confirmación de escritura (write concern).Obtener(wco)
          else
            write_concern = Nivel de confirmación de escritura (write concern).Obtener(w: mayoría, wtimeout: 10_000)
          end
        end
        especificación = {
          selector: { commitTransaction: 1 },
          db_name: 'admin',
          sesión: sí mismo,
          txn_num: txn_num,
          write_concern: write_concern,
        }
        Operación = Operación::Comando.Nuevo(especificación)
        trazador.trace_operation(Operación, context, op_name: 'commitTransaction') hacer
          Operación.execute_with_connection(Conexión, context: context)
        end
      end
    end
    # Finaliza el lapso de transacción antes de cambiar el estado
    trazador.finish_transaction_span(sí mismo)
  asegurar
    @state = ESTADO_DE_TRANSACCIÓN_CONFIRMADA
    @commit_transaction = false
  end

  # No hay valor de retorno oficial, pero retorna verdadero para que en interactivo
  # utiliza las sugerencias del método que tuvo éxito.
  true
end

#committing_transaction?true | false

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Devuelve si la sesión está actualmente confirmando una transacción.

Devuelve:

  • (true | false)

    Si la sesión está actualmente realizando una transacción.

Desde:

  • 2.5.0



891
892
893
# Archivo 'lib/mongo/session.rb', línea 891

def guardando_transacción?
  !!@commit_transaction
end

#¡sucio!( marcar = true) ⇒ objeto

Establece el estado "dirty" (modificado) en el valor dado para la sesión subyacente del servidor. Si no hay una sesión de servidor, esto no hace nada.

Parámetros:

  • marca (true | false) (por defecto: true)

    si se debe marcar la sesión del servidor como sucia o no.

Desde:

  • 2.5.0



139
140
141
# Archivo 'lib/mongo/session.rb', línea 139

def dirty!(marca = true)
  @server_session&.dirty!(marca)
end

#dirty?true | false | nil

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Devuelve si la sesión de servidor subyacente está sucia. Si no existe una sesión de servidor para esta sesión, se devuelve nil.

Devuelve:

  • (true | false | nil)

    si la sesión subyacente del servidor está sucia. Si no existe una sesión de servidor para esta sesión, devuelve nil.

Desde:

  • 2.5.0



147
148
149
# Archivo 'lib/mongo/session.rb', línea 147

def dirty?
  @server_session&.dirty?
end

#end_sessionnil

Finaliza esta sesión.

Si hay una transacción en curso en esta sesión, la transacción se aborta. La sesión del servidor asociada a esta sesión se devuelve al grupo de sesiones del servidor. Por último, esta sesión está marcada como finalizada y ya no se puede utilizar.

Si esta sesión ya finalizó, este método no hace nada.

Ten en cuenta que este método no emite directamente un comando endSessions a este servidor, contrario a lo que su nombre podría sugerir.

Ejemplos:

session.end_session

Devuelve:

  • (nil)

    Siempre nulo.

Desde:

  • 2.5.0



374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# Archivo 'lib/mongo/session.rb', línea 374

def end_session
  si !¿terminado? && @client
    si within_states?(TRANSACTION_IN_PROGRESS_STATE)
      begin
        abortar_transacción
      rescate mongo::Error, Error::AuthError
      end
    end
    # Libere cualquier conexión fijada (por ejemplo, después de una transacción confirmada)
    # en modo de balanceo de carga).
    unpin si pinned_connection_global_id
    clúster.session_pool.checkin(@server_session) si @server_session
  end
asegurar
  @server_session = nulo
  @se terminó = true
  @client = nulo
end

#ended?true, false

Si esta sesión ha finalizado.

Ejemplos:

session.ended?

Devuelve:

  • (true, false)

    Si la sesión ha terminado.

Desde:

  • 2.5.0



244
245
246
# Archivo 'lib/mongo/session.rb', línea 244

def ¿terminado?
  !!@se terminó
end

#¿explícito?true, false

¿Es esta una sesión explícita (es decir, creado por el usuario).

Ejemplos:

¿La sesión es explícita?

session.explicit?

Devuelve:

  • (true, false)

    Si esta sesión es explícita.

Desde:

  • 2.5.2



179
180
181
# Archivo 'lib/mongo/session.rb', línea 179

def explicit?
  !implicit?
end

#¿implícito?true, false

¿Esta sesión es implícita (no creada por el usuario)?.

Ejemplos:

¿La sesión es implícita?

session.implicit?

Devuelve:

  • (true, false)

    Si esta sesión es implícita.

Desde:

  • 2.5.1



167
168
169
# Archivo 'lib/mongo/session.rb', línea 167

def implicit?
  @implicit ||= !!(@options.key?(:implicit) && @options[:implicit] == true)
end

#in_transaction?true | false

Si la sesión está o no actualmente en una transacción.

Ejemplos:

¿Está la sesión en una transacción?

session.in_transaction?

Devuelve:

  • (true | false)

    Si la sesión en una transacción se realiza o no.

Desde:

  • 2.6.0



883
884
885
# Archivo 'lib/mongo/session.rb', línea 883

def en_transacción?
  within_states?(STARTING_TRANSACTION_STATE, TRANSACTION_IN_PROGRESS_STATE)
end

#inside_with_transaction?Boolean

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Retorna si estamos actualmente dentro de un bloque with_transaction.

Devuelve:

  • (booleano)

    Si nos encontramos actualmente dentro de un bloque with_transaction.

Desde:

  • 2.5.0



1278
1279
1280
# Archivo 'lib/mongo/session.rb', línea 1278

def adentro_con_transacción?
  @inside_with_transaction
end

#inspectString

Obtén una string formateada para usar en la inspección.

Ejemplos:

Inspecciona el objeto de sesión.

session.inspect

Devuelve:

  • (string)

    La inspección de la sesión.

Desde:

  • 2.5.0



352
353
354
# Archivo 'lib/mongo/session.rb', línea 352

def inspeccionar
  "#<Mongo::Session:0x#{object_id} session_id=#{session_id} options=#{@options}>"
end

#materialize_if_neededSesión

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Si aún no está configurado, rellene el server_session de un objeto de sesión sacando una sesión del grupo de sesiones.

Devuelve:

Aumenta:

Desde:

  • 2.5.0



1223
1224
1225
1226
1227
1228
1229
1230
1231
# Archivo 'lib/mongo/session.rb', línea 1223

def materialize_if_needed
  propagar Error::SessionEnded si ¿terminado?

  return a menos que implicit? && !@server_session

  @server_session = clúster.session_pool.checkout

  sí mismo
end

#¿materializado?Booleano

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Devuelve:

  • (booleano)

Aumenta:

Desde:

  • 2.5.0



1234
1235
1236
1237
1238
# Archivo 'lib/mongo/session.rb', línea 1234

def ¿materializado?
  propagar Error::SessionEnded si ¿terminado?

  !@server_session.nil?
end

#next_txn_numInteger

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Incrementa y devuelve el siguiente número de transacción.

Ejemplos:

Obtén el siguiente número de transacción.

session.next_txn_num

Devuelve:

  • (Número entero)

    El número de la siguiente transacción.

Aumenta:

Desde:

  • 2.5.0



1249
1250
1251
1252
1253
# Archivo 'lib/mongo/session.rb', línea 1249

def next_txn_num
  propagar Error::SessionEnded si ¿terminado?

  @server_session.next_txn_num
end

#pin_to_connection(connection_global_id, connection: nil) ⇒ objeto

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Fijar esta sesión en la conexión especificada.

esta sesión a.

Parámetros:

  • connection_global_id (Número entero)

    El id global de la conexión para fijar

  • Conexión (Conexión | nil) (valor por defecto: nil)

    El objeto de conexión al que fijar.

Aumenta:

  • (ArgumentError)

Desde:

  • 2.5.0



925
926
927
928
929
930
# Archivo 'lib/mongo/session.rb', línea 925

def pin_to_connection(connection_global_id, conexión: nulo)
  propagar ArgumentError, 'No se puede fijar en una id de conexión nula' si connection_global_id.nil?

  @pinned_connection_global_id = connection_global_id
  @pinned_connection = Conexión
end

#pin_to_server(server) ⇒ Objeto

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Ancla esta sesión al servidor especificado, que debería ser un mongos.

Parámetros:

  • Server (servidor)

    El servidor al que fijar esta sesión.

Aumenta:

  • (ArgumentError)

Desde:

  • 2.5.0



908
909
910
911
912
913
914
915
916
# Archivo 'lib/mongo/session.rb', línea 908

def pin_to_server(Server)
  propagar ArgumentError, 'No se puede fijar a un servidor nulo' si Server.nil?

  si Lint.¿habilitado? && !Server.mongos?
    propagar Error::LintError, "Intentó vincular la sesión al servidor #{servidor.resumen} que no es un mongos"
  end

  @pinned_server = Server
end

#proceso(resultado) ⇒ Operación::Resultado

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Procesar una respuesta del servidor que utilizó esta sesión.

Ejemplos:

Procesar una respuesta del servidor.

session.process(result)

Parámetros:

Devuelve:

Desde:

  • 2.5.0



1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
# Archivo 'lib/mongo/session.rb', línea 1183

def Proceso(Resultado)
  a menos que implicit?
    set_operation_time(Resultado)
    si cluster_time_doc = Resultado.cluster_time
      advance_cluster_time(cluster_time_doc)
    end
  end
  @server_session.set_last_use!

  si (doc = Resultado.respuesta && Resultado.respuesta.Documentos.primero) && doc[:recoveryToken]
    sí mismo.recovery_token = doc[:recoveryToken]
  end

  Resultado
end

#reintentar_lecturas?booleano

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Si las lecturas ejecutadas con esta sesión se pueden reintentar de acuerdo con la especificación moderna de lecturas reintentables.

Si este método devuelve true, la aplicación ha solicitado las lecturas modernas reintentables. Si el servidor seleccionado para una operación de lectura admite lecturas modernas reintentables, se utilizarán para esa operación en particular. Si el servidor seleccionado para una operación de lectura no admite lecturas reintentables modernas, la lectura no se reintentará.

Si este método devuelve falso, la aplicación ha solicitado lecturas repetibles heredadas. La lógica heredada de lectura reintentable se utilizará independientemente de la versión del servidor al que esté conectado el cliente. El número de reintentos de lectura está determinado por la opción del cliente :max_read_retries, que por defecto es 1 y puede establecerse en 0 para desactivar los reintentos de lectura legados.

Devuelve:

  • (booleano)

Desde:

  • 2.5.0



199
200
201
# Archivo 'lib/mongo/session.rb', línea 199

def retry_reads?
  Cliente.opciones[:retry_reads] != false
end

#retry_writes?true, false

Nota:

Las escrituras reintentables solo están disponibles con clústeres, sets de réplicas o topologías con balanceo de carga.

¿Se reintentarán los guardados ejecutados con esta sesión?

Ejemplos:

¿Se volverán a intentar los guardados?

session.retry_writes?

Devuelve:

  • (true, false)

    Si se reintentarán los guardados.

Desde:

  • 2.5.0



214
215
216
# Archivo 'lib/mongo/session.rb', línea 214

def ¿retry_writes?
  !!Cliente.opciones[retry_writes] && (clúster.replica_set? || clúster.particionado? || clúster.balanceo_de_carga?)
end

#revert_to_starting_transaction!Objeto

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Revierte el estado de la sesión a STARTING_TRANSACTION_STATE. Se llama antes de reintentar el primer comando en una transacción para que startTransaction: true se conserve en el reintento.

Desde:

  • 2.5.0



1134
1135
1136
1137
1138
# Archivo 'lib/mongo/session.rb', línea 1134

def revertir_a_transacción_inicial!
  return a menos que within_states?(TRANSACTION_IN_PROGRESS_STATE)

  @state = STARTING_TRANSACTION_STATE
end

#session_idBSON::Document

Obtén el ID de sesión del servidor para esta sesión, si la sesión no se ha terminado. Si la sesión había terminado, genera Error::SessionEnded.

Devuelve:

  • (BSON::Document)

    El id de la sesión del servidor.

Aumenta:

Desde:

  • 2.5.0



256
257
258
259
260
261
262
263
264
265
266
267
268
269
# Archivo 'lib/mongo/session.rb', línea 256

def session_id
  propagar Error::SessionEnded si ¿terminado?

  # Una sesión explícita siempre tendrá un session_id, porque durante
  # construction debe proporcionarse una sesión de servidor. Una sesión implícita
  # no tendría un session_id hasta materializarse, por lo tanto las llamadas a
  # session_id podría fallar. Una aplicación no debería tener una oportunidad
  # para experimentar esta falla porque una sesión implícita no debería ser
  # accesible a las aplicaciones debido a que su tiempo de vida está restringido a
  # ejecución de la operación, que se realiza íntegramente por el driver.
  propagar Error::SesiónNoMaterializada a menos que ¿materializado?

  @server_session.session_id
end

#snapshot?true | false

Devuelve si la sesión está configurada para lecturas de snapshot.

Devuelve:

  • (true | false)

    Si la sesión está configurada para lecturas de snapshot.

Desde:

  • 2.5.0



123
124
125
# Archivo 'lib/mongo/session.rb', línea 123

def snapshot?
  !!opciones[snapshot]
end

#start_transaction(options = nil) ⇒ Object

Ubica las operaciones posteriores en esta sesión en una nueva transacción.

Tenga en cuenta que la transacción no se iniciará en el servidor hasta que se realice una operación después de llamar a start_transaction.

Ejemplos:

Inicia una nueva transacción

session.start_transaction(options)

Parámetros:

  • opciones (encriptada) (valor por defecto: nil)

    Las opciones para la transacción que se está iniciando.

Opciones Hash (options):

  • tiempo_máximo_de_commit_ms (Integer)

    El tiempo máximo permitido para que se ejecute un solo comando commitTransaction, en milisegundos. Esta opción está obsoleta, utiliza :timeout_ms en su lugar.

  • :read_concern (encriptada)

    El hash de opciones de nivel de consistencia de lectura, con las siguientes claves opcionales:

    • :level -- el nivel de preferencia de lectura como símbolo; los valores válidos son :local, :majority y :snapshot
  • conformidad_de_lectura (encriptada)

    Las opciones de nivel de confirmación de escritura (write concern). Puede ser :w => Integer | String, :fsync => booleano, :j => booleano.

  • :leer (encriptada)

    Las opciones de preferencia de lectura. El hash puede tener los siguientes elementos:

    • :mode -- preferencia de lectura especificada como un símbolo; el único valor válido es :primary.
  • :timeout_ms (Integer)

    El tiempo de espera de la operación en milisegundos. Debe ser un número entero no negativo. Un valor explícito de 0 significa infinito. El valor por defecto no está definido, lo que significa que se hereda del cliente.

Aumenta:

Desde:

  • 2.6.0



653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
# Archivo 'lib/mongo/session.rb', línea 653

def start_transaction(opciones = nulo)
  verifica_transacciones_soportadas!

  si opciones
    Lint.validate_read_concern_option(opciones[:read_concern])

    # # Sería útil detectar preferencias de lectura no válidas aquí, pero
    #         # algunas de las pruebas de especificación requieren una detección posterior de preferencias de lectura no válidas.
    #         # Tal vez podamos hacer esto cuando el modo de lint esté activado.
    #         mode = options[:read] && options[:read][:mode].to_s
    #         si el modo && mode != 'primary'
    #           raise Mongo::Error::InvalidTransactionOperation.new(
    #             "la preferencia de lectura en una transacción debe ser primaria (solicitada: #{mode})"
    #           )
    #         end
  end

  propagar mongo::Error::SnapshotSessionTransactionProhibited si snapshot?

  check_if_ended!

  si within_states?(STARTING_TRANSACTION_STATE, TRANSACTION_IN_PROGRESS_STATE)
    propagar mongo::Error::OperaciónTransacciónInválida.Nuevo(
      mongo::Error::OperaciónTransacciónInválida::TRANSACCIÓN YA EN CURSO
    )
  end

  unpin

  next_txn_num
  @txn_options = (@options[:default_transaction_options] || {}).fusionar(opciones || {})

  si txn_write_concern && !Nivel de confirmación de escritura (write concern).Obtener(txn_write_concern).¿entendido?
    propagar mongo::Error::OperaciónTransacciónInválida.Nuevo(
      mongo::Error::OperaciónTransacciónInválida::UNACKNOWLEDGED_WRITE_CONCERN
    )
  end

  @state = STARTING_TRANSACTION_STATE
  @already_committed = false
  trazador.start_transaction_span(sí mismo)

  # Este método no tiene un valor de retorno explícito.
  # Aquí podríamos devolver nil, pero true indica al usuario que el
  # operación exitosa. Esto está destinado al uso interactivo.
  # Tenga en cuenta que el valor de retorno no está documentado.
  true
end

#starting_transaction?Booleano

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Devuelve:

  • (booleano)

Desde:

  • 2.5.0



871
872
873
# Archivo 'lib/mongo/session.rb', línea 871

def ¿iniciando_transacción?
  within_states?(STARTING_TRANSACTION_STATE)
end

#suppress_read_write_concern!(comando) ⇒ Hash, BSON::Document

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Elimine el nivel de consistencia de lectura y/o el nivel de confirmación de escritura (write concern) del comando si no aplica.

Ejemplos:

session.suppress_read_write_concern!(cmd)

Devuelve:

  • (Hash, BSON::Document)

    El documento del comando.

Desde:

  • 2.6.0



1098
1099
1100
1101
1102
1103
1104
1105
# Archivo 'lib/mongo/session.rb', línea 1098

def suprimir_nivel_lectura_escritura!(Comando)
  Comando.tocar hacer |C|
    Next a menos que en_transacción?

    C.borrar(Preocupación de lectura) a menos que ¿iniciando_transacción?
    C.borrar(:writeConcern) a menos que C[:commitTransaction] || C[abortTransaction]
  end
end

#txn_numInteger

Obtén el número de transacción actual.

Ejemplos:

Obtén el número de transacción actual.

session.txn_num

Devuelve:

  • (Número entero)

    El número de transacción actual.

Aumenta:

Desde:

  • 2.6.0



1263
1264
1265
1266
1267
# Archivo 'lib/mongo/session.rb', línea 1263

def txn_num
  propagar Error::SessionEnded si ¿terminado?

  @server_session.txn_num
end

#txn_optionsHash

en esta sesión.

Devuelve:

  • (encriptada)

    Las opciones para la transacción que se está ejecutando actualmente

Desde:

  • 2.6.0



155
156
157
# Archivo 'lib/mongo/session.rb', línea 155

def txn_options
  @txn_options or propagar ArgumentError, 'No hay ninguna transacción activa'
end

#txn_read_preferenceHash

Obtenga la preferencia de lectura que la sesión usará en la transacción actualmente activa.

Esto es un hash de estilo de controlador con claves de guion bajo.

Ejemplos:

Obtener la preferencia de lectura de la transacción

session.txn_read_preference

Devuelve:

  • (encriptada)

    La preferencia de lectura de la transacción.

Desde:

  • 2.6.0



229
230
231
232
233
234
# Archivo 'lib/mongo/session.rb', línea 229

def preferencia_de_lectura_txn
  rp = txn_options[:leer] ||
       @client.read_preference
  mongo::Lint.validate_underscore_read_preference(rp)
  rp
end

#desanclar(conexión = nil) ⇒ objeto

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Desancla esta sesión del servidor o conexión anclada, si la sesión estaba anclada.

Parámetros:

  • Conexión (Conexión | nil) (valor por defecto: nil)

    Conexión para desanclar.

Desde:

  • 2.5.0



938
939
940
941
942
943
944
945
946
947
948
949
950
951
# Archivo 'lib/mongo/session.rb', línea 938

def unpin(Conexión = nulo)
  @pinned_server = nulo
  @pinned_connection_global_id = nulo
  conn = Conexión || @pinned_connection
  si conn
    conn.unpin(transacción)
    # Comprobar la conexión de nuevo al grupo solo si no hay nada más
    # Todavía mantiene un pin en él (por ejemplo, un cursor abierto).
    a menos que conn.¿fijado?
      conn.connection_pool.registrar(conn)
    end
  end
  @pinned_connection = nulo
end

#unpin_maybe(error, conexión = nil) ⇒ Objeto

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Desancla esta sesión del servidor o conexión anclados, si la sesión estaba anclada y la instancia de excepción especificada y el estado de transacción de la sesión requieren que se desancle.

La instancia de excepción ya debería tener todas las etiquetas establecidas (tanto las generadas por el cliente como las generadas por el servidor).

Parámetros:

  • Error (Error)

    La instancia de excepción para procesar.

  • Conexión (Conexión | nil) (valor por defecto: nil)

    Conexión para desanclar.

Desde:

  • 2.5.0



964
965
966
967
968
969
970
971
972
973
974
# Archivo 'lib/mongo/session.rb', línea 964

def desanclar_posiblemente(Error, Conexión = nulo)
  si !within_states?(sesión::NO_TRANSACTION_STATE) &&
     Error.¿etiqueta?('TransientTransactionError')
    unpin(Conexión)
  end

  si guardando_transacción? &&
     Error.¿etiqueta?('UnknownTransactionCommitResult')
    unpin(Conexión)
  end
end

#update_state!Object

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Actualiza el estado de la sesión debido a la ejecución de una operación (ni confirmación ni abortar).

Desde:

  • 2.6.0



1144
1145
1146
1147
1148
1149
1150
1151
# Archivo 'lib/mongo/session.rb', línea 1144

def update_state!
  caso @state
  cuando STARTING_TRANSACTION_STATE
    @state = TRANSACTION_IN_PROGRESS_STATE
  cuando ESTADO_DE_TRANSACCIÓN_CONFIRMADA, TRANSACTION_ABORTED_STATE
    @state = NO_TRANSACTION_STATE
  end
end

#validate!(client) ⇒ Session

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Valida la sesión para que la use el cliente especificado.

La sesión no debe terminarse y debe haber sido creada por un cliente que pertenezca al mismo clúster que el cliente con el que se va a usar la sesión.

Parámetros:

  • Cliente (cliente)

    El cliente con el que debe usarse la sesión.

Devuelve:

  • (Sesión)

    yo, si la sesión es válida.

Aumenta:

Desde:

  • 2.5.0



1166
1167
1168
1169
1170
# Archivo 'lib/mongo/session.rb', línea 1166

def validate!(Cliente)
  check_if_ended!
  check_matching_cluster!(Cliente)
  sí mismo
end

#validate_read_preference!(comando) ⇒ Objeto

Este método es parte de una API privada. Se debe evitar el uso de este método si es posible, ya que podría eliminarse o modificarse en el futuro.

Asegúrate de que la preferencia de lectura de un comando sea primaria.

Ejemplos:

session.validate_read_preference!(command)

Aumenta:

Desde:

  • 2.6.0



1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
# Archivo 'lib/mongo/session.rb', línea 1117

def validate_read_preference!(Comando)
  return a menos que en_transacción?
  return a menos que Comando['$readPreference']

  moda = Comando['$readPreference']['mode'] || Comando['$readPreference'][moda]

  return a menos que moda && moda != 'primario/a'

  propagar mongo::Error::OperaciónTransacciónInválida.Nuevo(
    "la preferencia de lectura en una transacción debe ser primaria (solicitada: #{modo})"
  )
end

#with_transaction(opciones = nil) ⇒ Objeto

Nota:

with_transaction contiene un bucle, por lo tanto, si with_transaction en sí mismo se coloca en un bucle, su bloque no debe llamar a siguiente o break para controlar el bucle externo porque esto, en cambio, afectará al bucle en with_transaction. El controlador advertirá y abortará la transacción si detecta esta situación.

Ejecuta el bloque proporcionado en una transacción, reintentando según sea necesario.

Devuelve el valor de retorno del bloque.

El número exacto de reintentos y cuándo se realizan son detalles de implementación del controlador; el bloque proporcionado debe ser idempotente y debe estar preparado para ser llamado más de una vez. El driver puede reintentar el comando de confirmación dentro de una transacción activa o puede repetir la transacción e invocar el bloque nuevamente, dependiendo del error encontrado, si lo hubiera. Tenga en cuenta también que los reintentos pueden ejecutarse contra diferentes servidores.

Las transacciones no pueden anidarse: se generará InvalidTransactionOperation si este método se llama cuando la sesión ya tiene una transacción activa.

Las excepciones generadas por el bloque que no derivan de Mongo::Error detienen el procesamiento, cancelan la transacción y se propagan fuera de with_transaction. Las excepciones derivadas de Mongo::Error pueden ser gestionadas por with_transaction, resultando en reintentos del proceso.

Actualmente, with_transaction volverá a intentar los commits y las invocaciones bloqueadas hasta que hayan transcurrido al menos 120 segundos desde que with_transaction comenzó a ejecutarse. Este plazo de espera no es configurable y podría cambiar en una futura versión del controlador.

Ejemplos:

Ejecución de una instrucción en una transacción

session.with_transaction(write_concern: {w: :majority}) do
  collection.update_one({ id: 3 }, { '$set' => { status: 'Inactive'} },
                        session: session)

end

Ejecuta una instrucción en una transacción, limitando el tiempo total consumido

Timeout.timeout(5) do
  session.with_transaction(write_concern: {w: :majority}) do
    collection.update_one({ id: 3 }, { '$set' => { status: 'Inactive'} },
                          session: session)

  end
end

Parámetros:

  • opciones (encriptada) (valor por defecto: nil)

    Las opciones para la transacción que se inicia. Estas son las mismas opciones que acepta start_transaction.

Aumenta:

Desde:

  • 2.7.0



447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
# Archivo 'lib/mongo/session.rb', línea 447

def with_transaction(opciones = nulo)
  @inside_with_transaction = true
  @with_transaction_timeout_ms = opciones&.dig(:timeout_ms) || @options[:default_timeout_ms] || @client.timeout_ms
  @with_transaction_deadline = calculate_with_transaction_deadline(opciones)
  fecha límite = si @with_transaction_deadline
               # CSOT habilitado, por lo que tenemos una fecha límite definida por el cliente.
               @with_transaction_deadline
             else
               # CSOT no está habilitado, así que usamos el plazo por defecto, 120 segundos.
               Utils.monotonic_time + 120
             end
  operación en curso = false
  intento_de_transacción = 0
  último_error = nulo
  overload_error_count = 0
  sobrecarga encontrada = false

  bucle hacer
    si intento_de_transacción > 0
      si sobrecarga encontrada
        retrasar = @client.retry_policy.retraso_de_respaldo(overload_error_count)
        si ¿el retroceso excedería el plazo?(fecha límite, retrasar)
          make_timeout_error_from(último_error, 'El tiempo de espera de CSOT expiró esperando para reintentar conTransaction')
        end
        propagar(último_error) a menos que @client.retry_policy.should_retry_overload?(overload_error_count, retrasar)

        sueño(retrasar)
      else
        retroceso = backoff_seconds_for_retry(intento_de_transacción)
        si ¿el retroceso excedería el plazo?(fecha límite, retroceso)
          make_timeout_error_from(último_error, 'El tiempo de espera de CSOT expiró esperando para reintentar conTransaction')
        end

        sueño(retroceso)
      end
    end

    commit_options = {}
    commit_options[conformidad_de_lectura] = opciones[conformidad_de_lectura] si opciones
    start_transaction(opciones)
    operación en curso = true
    intento_de_transacción += 1

    begin
      rv = rendimiento sí mismo
    rescate Excepción => e
      si within_states?(STARTING_TRANSACTION_STATE, TRANSACTION_IN_PROGRESS_STATE)
        log_warn("Abortando la transacción debido a #{e.clase}: #{e}")
        # CSOT: si la fecha límite ya ha expirado, bórrela para que
        # abort_transaction utiliza un tiempo de espera nuevo (no el plazo expirado).
        # Si el plazo aún no ha vencido, mantenlo para que la operación de "abort" use el tiempo restante.
        @with_transaction_deadline = nulo si @with_transaction_deadline && ¿plazo_vencido?(fecha límite)
        abortar_transacción
        operación en curso = false
      end

      si ¿plazo_vencido?(fecha límite)
        operación en curso = false
        make_timeout_error_from(e, 'Tiempo de espera de CSOT agotado durante la función de retorno en withTransaction')
      end

      si e.is_a?(mongo::Error) && e.¿etiqueta?('TransientTransactionError')
        último_error = e
        si e.¿etiqueta?('SystemOverloadedError')
          sobrecarga encontrada = true
          overload_error_count += 1
        elsif sobrecarga encontrada
          overload_error_count += 1
        end
        Next
      end

      propagar
    else
      si within_states?(TRANSACTION_ABORTED_STATE, NO_TRANSACTION_STATE, ESTADO_DE_TRANSACCIÓN_CONFIRMADA)
        operación en curso = false
        return rv
      end

      # CSOT: si el tiempo de espera ha expirado antes de que podamos confirmar, abortar el
      # transacción en su lugar y generar un error de tiempo de espera del lado del cliente.
      si @with_transaction_deadline && ¿plazo_vencido?(fecha límite)
        operación en curso = false
        @with_transaction_deadline = nulo
        abortar_transacción
        propagar mongo::Error::TimeoutError, 'El tiempo de espera CSOT expiró antes de que la transacción pudiera ser confirmada'
      end

      begin
        commit_transaction(commit_options)
        operación en curso = false
        return rv
      rescate mongo::Error => e
        si e.¿etiqueta?('UnknownTransactionCommitResult')
          si ¿plazo_vencido?(fecha límite) ||
             (e.is_a?(Error::OperationFailure::Familia) && e.¿max_time_ms_expired?)
            operación en curso = false

            propagar a menos que @with_transaction_timeout_ms && ¿plazo_vencido?(fecha límite)

            make_timeout_error_from(e, 'El tiempo de espera de CSOT expiró durante la confirmación de withTransaction')
          end

          si e.¿etiqueta?('SystemOverloadedError')
            sobrecarga encontrada = true
            overload_error_count += 1
          elsif sobrecarga encontrada
            overload_error_count += 1
          end

          si sobrecarga encontrada
            retrasar = @client.retry_policy.retraso_de_respaldo(overload_error_count)
            si ¿el retroceso excedería el plazo?(fecha límite, retrasar)
              operación en curso = false
              make_timeout_error_from(e, 'El tiempo de espera de CSOT expiró durante la confirmación de withTransaction')
            end
            a menos que @client.retry_policy.should_retry_overload?(overload_error_count, retrasar)
              operación en curso = false
              propagar
            end
            sueño(retrasar)
          end

          wc_options = caso v = commit_options[conformidad_de_lectura]
                       cuando Nivel de confirmación de escritura (write concern)::Base
                         v.opciones
                       cuando nulo
                         {}
                       else
                         v
                       end
          commit_options[conformidad_de_lectura] = wc_options.fusionar(w: mayoría)
          reintentar
        elsif e.¿etiqueta?('TransientTransactionError')
          si Utils.monotonic_time >= fecha límite
            operación en curso = false
            make_timeout_error_from(e, 'El tiempo de espera de CSOT expiró durante la confirmación de withTransaction')
          end
          último_error = e
          si e.¿etiqueta?('SystemOverloadedError')
            sobrecarga encontrada = true
            overload_error_count += 1
          elsif sobrecarga encontrada
            overload_error_count += 1
          end
          @state = NO_TRANSACTION_STATE
          Next
        else
          operación en curso = false
          propagar
        end
      rescate Error::AuthError
        operación en curso = false
        propagar
      end
    end
  end

  # No hay valor de retorno oficial, pero retorna verdadero para que en interactivo
  # utiliza las sugerencias del método que tuvo éxito.
  true
asegurar
  si operación en curso
    log_warn('La función de retorno with_transaction salió del bucle with_transaction, abortando la transacción')
    begin
      abortar_transacción
    rescate Error::OperationFailure::Familia, Error::OperaciónTransacciónInválida
    end
  end
  @with_transaction_deadline = nulo
  @with_transaction_timeout_ms = nulo
  @inside_with_transaction = false
end