Clase: Mongo::Session
- Hereda:
-
Objeto
- Objeto
- Mongo::Session
- 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
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.
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.
'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.
'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.
'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.
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.
: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.
: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.
: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.
: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.
[ 79, # UnknownReplWriteConcern 100, # CannotSatisfyWriteConcern, ].freeze
Constantes incluidas desde Loggable
Resumen de atributos de la instancia colapsar
-
#client ⇒ Client
Solo lectura
El cliente a través del cual se creó esta sesión.
- #cluster ⇒ Object Solo lectura
-
#operation_time ⇒ BSON::Timestamp
Solo lectura
El último operation time visto para esta sesión.
-
#options ⇒ Hash
Solo lectura
Las opciones para esta sesión.
-
#pinned_connection_global_id ⇒ Integer | nil
Solo lectura
privado
El ID global de conexión al que esta sesión está fijada, si corresponde.
-
#pinned_server ⇒ Server | nil
Solo lectura
privado
El servidor (que debe ser un mongos) al que está fijada esta sesión, si existe.
-
#recovery_token ⇒ BSON::Document | nil
privado
Token de recuperación para la transacción fragmentada que se está ejecutando en esta sesión, si la hubiera.
-
#snapshot_timestamp ⇒ BSON::Timestamp | nil
La hora de la snapshot de esta sesión.
-
#with_transaction_deadline ⇒ Integer | nil
Solo lectura
privado
La fecha límite para la transacción actual, si existe.
Atributos incluidos de ClusterTime::Consumer
Resumen del método de instancia colapsar
-
#abort_transaction(options = nil) ⇒ Object
Aborta la transacción activa actualmente sin realizar ningún cambio en la base de datos.
-
#aborting_transaction? ⇒ true | false
privado
Si la sesión está abortando actualmente una transacción.
-
#add_autocommit!(comando) ⇒ Hash, BSON::documento
privado
Agregar el campo de autocommit a un documento de comando si corresponde.
-
#add_start_transaction!(command) ⇒ Hash, BSON::Document
privado
Agregar el campo startTransaction a un documento de comando si es aplicable.
-
#add_txn_num!(comando) ⇒ Hash, BSON::Document
privado
Agrega el número de transacción a un documento de comando si corresponde.
-
#add_txn_opts!(comando, _read, contexto) ⇒ Hash, BSON::Document
privado
Agregue las opciones de transacciones si corresponde.
-
#advance_operation_time(new_operation_time) ⇒ BSON::Timestamp
Avanza el operation time en caché para esta sesión.
-
#causal_consistency_doc ⇒ Objeto
privado
Devuelve el documento de coherencia causal si se conoce el optime y la coherencia causal está habilitada; de lo contrario, devuelve nil.
-
#commit_transaction(options = nil) ⇒ objeto
Confirma la transacción activa actual en la sesión.
-
#declarando_transacción? ⇒ true | false
privado
Si la sesión está actualmente realizando una transacción.
-
#dirty!(mark = true) ⇒ objeto
Establece el estado sucio al valor dado para la sesión de servidor subyacente.
-
#dirty? ⇒ true | false | nil
privado
Si la sesión del servidor subyacente está sucia.
-
#end_session ⇒ nil
Finaliza esta sesión.
-
#¿finalizó? ⇒ true, false
Si esta sesión ha finalizado.
-
#explicito? ⇒ verdadero, falso
¿Es esta una sesión explícita (es decir, creado por el usuario).
-
#implícito? ⇒ verdadero, falso
¿Esta sesión es implícita (no creada por el usuario)?.
-
#en_transacción? ⇒ verdadero | falso
Si la sesión está o no actualmente en una transacción.
-
#inicializar(server_session, cliente, options = {}) ⇒ sesión
constructor
privado
Iniciar una sesión.
-
#inside_with_transaction? ⇒ Boolean
privado
Si nos encontramos actualmente dentro de un bloque with_transaction.
-
#inspect ⇒ string
Obtén una string formateada para usar en la inspección.
-
#materialize_if_needed ⇒ Sesión
privado
Si aún no está configurado, rellene el server_session de un objeto de sesión sacando una sesión del grupo de sesiones.
- #materialized? ⇒ Booleano privado
-
#next_txn_num ⇒ número entero
privado
Incrementa y devuelve el siguiente número de transacción.
-
#pin_to_connection(connection_global_id, connection: nil) ⇒ Object
privado
Fijar esta sesión en la conexión especificada.
-
#pin_to_servidor(servidor) ⇒ objeto
privado
Ancla esta sesión al servidor especificado, que debería ser un mongos.
-
#procesar(resultado) ⇒ Operación::Resultado
privado
Procesar una respuesta del servidor que utilizó esta sesión.
-
#reintentar_lecturas? ⇒ booleano
privado
Si las lecturas ejecutadas con esta sesión se pueden reintentar de acuerdo con la especificación moderna de lecturas reintentables.
-
#retry_writes? ⇒ verdadero, falso
¿Se reintentarán los guardados ejecutados con esta sesión?
-
#revert_to_starting_transaction! ⇒ Object
privado
Revierte el estado de la sesión a STARTING_TRANSACTION_STATE.
-
#session_id ⇒ BSON::Document
Obtén el ID de sesión del servidor de esta sesión, si la sesión no se ha terminado.
-
#snapshot? ⇒ true | false
Si la sesión está configurada para lecturas de snapshot.
-
#start_transaction(opciones = nil) ⇒ Objeto
Ubica las operaciones posteriores en esta sesión en una nueva transacción.
- #starting_transaction? ⇒ booleano privado
-
#suppress_read_write_concern!(comando) ⇒ Hash, BSON::Document
privado
Elimine el nivel de consistencia de lectura y/o el nivel de confirmación de escritura (write concern) del comando si no aplica.
-
#txn_num ⇒ Integer
Obtén el número de transacción actual.
-
#txn_options ⇒ Hash
en esta sesión.
-
#txn_read_concern ⇒ Hash
privado
Obtenga el nivel de consistencia de lectura que utilizará la sesión al iniciar una transacción.
-
#txn_read_preference ⇒ Hash
Obtenga la preferencia de lectura que la sesión usará en la transacción actualmente activa.
-
#desanclar(conexión = nil) ⇒ Objeto
privado
Desancla esta sesión del servidor o conexión anclada, si la sesión estaba anclada.
-
#unpin_maybe(error, connection = nil) ⇒ Objeto
privado
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.
-
#update_state! ⇒ Object
privado
Actualiza el estado de la sesión debido a la ejecución de una operación (ni confirmación ni abortar).
-
#validate!(client) ⇒ Session
privado
Valida la sesión para que la use el cliente especificado.
-
#validate_read_preference!(command) ⇒ objeto
privado
Asegúrate de que la preferencia de lectura de un comando sea primaria.
-
#with_transaction(options = nil) ⇒ objeto
Ejecuta el bloque proporcionado en una transacción, reintentando según sea necesario.
Métodos incluidos de ClusterTime::Consumer
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.
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.
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 108 109 110 111 112 113 114 115 116 117 118 |
# Archivo 'lib/mongo/session.rb', línea 82 def inicializar(server_session, Cliente, = {}) si [:consistencia_causal] && [snapshot] propagar ArgumentError, ':las opciones :causal_consistency y :snapshot no pueden configurarse ambas en una sesión' end si [:snapshot_time] && ![snapshot] propagar ArgumentError, ':snapshot_time solo se puede establecer cuando :snapshot es verdadero' end si [:snapshot_time] && ![:snapshot_time].is_a?(BSON::Marca de tiempo) propagar ArgumentError, ':snapshot_time debe ser un BSON::Timestamp' end si [: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 = .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 = [:implicit] ? Cliente : Cliente.Usar(Administrador) @cluster = @client.clúster @options = .dup.freeze @cluster_time = nulo @state = NO_TRANSACTION_STATE @with_transaction_deadline = nulo @with_transaction_timeout_ms = nulo @inside_with_transaction = false @snapshot_timestamp = [:snapshot_time] end |
Detalles de atributo de instancias
#cliente ⇒ Cliente (solo lectura)
Devuelve El cliente a través del cual se creó esta sesión.
128 129 130 |
# Archivo 'lib/mongo/session.rb', línea 128 def Cliente @client end |
#clúster ⇒ Objeto (solo lectura)
130 131 132 |
# Archivo 'lib/mongo/session.rb', línea 130 def clúster @cluster end |
#operation_time ⇒ BSON::Timestamp (solo lectura)
Devuelve el operation time más reciente visto para esta sesión.
141 142 143 |
# Archivo 'lib/mongo/session.rb', línea 141 def tiempo_de_operación @operation_time end |
#opciones ⇒ Hash (solo lectura)
Devuelve las opciones para esta sesión.
123 124 125 |
# Archivo 'lib/mongo/session.rb', línea 123 def @options end |
#pinned_connection_global_id ⇒ Entero | 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.
292 293 294 |
# Archivo 'lib/mongo/session.rb', línea 292 def pinned_connection_global_id @pinned_connection_global_id end |
#pinned_server ⇒ Servidor | 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.
286 287 288 |
# Archivo 'lib/mongo/session.rb', línea 286 def servidor anclado @pinned_server end |
#recovery_token ⇒ BSON::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.
298 299 300 |
# Archivo 'lib/mongo/session.rb', línea 298 def recovery_token @recovery_token end |
#snapshot_timestamp ⇒ BSON::Timestamp | nil
Devuelve La hora de snapshot de esta sesión. nil si la sesión no es una sesión de snapshot, o si es una sesión de snapshot para la que no se proporcionó ninguna opción :snapshot_time y aún no se ha capturado ninguna lectura de atClusterTime del servidor.
1287 1288 1289 |
# Archivo 'lib/mongo/session.rb', línea 1287 def @snapshot_timestamp end |
#con_plazo_para_la_transacción ⇒ Integer | 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.
1303 1304 1305 |
# Archivo 'lib/mongo/session.rb', línea 1303 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.
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 869 870 871 872 873 874 875 |
# Archivo 'lib/mongo/session.rb', línea 810 def abortar_transacción( = 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 ||= {} 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() ) escribir_con_reintento([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.
906 907 908 |
# Archivo 'lib/mongo/session.rb', línea 906 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.
999 1000 1001 1002 1003 |
# Archivo 'lib/mongo/session.rb', línea 999 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.
1014 1015 1016 1017 1018 |
# Archivo 'lib/mongo/session.rb', línea 1014 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.
1029 1030 1031 1032 1033 |
# Archivo 'lib/mongo/session.rb', línea 1029 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.
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 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 |
# Archivo 'lib/mongo/session.rb', línea 1044 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 = [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.
1223 1224 1225 1226 1227 1228 1229 |
# Archivo 'lib/mongo/session.rb', línea 1223 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 |
#causal_consistency_doc ⇒ 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.
Devuelve el documento de coherencia causal si se conoce el optime y la coherencia causal está habilitada; de lo contrario, devuelve nil.
1331 1332 1333 1334 1335 |
# Archivo 'lib/mongo/session.rb', línea 1331 def causal_consistency_doc return a menos que tiempo_de_operación && causal_consistency? { afterClusterTime: tiempo_de_operación } end |
#commit_transaction(opciones = nil) ⇒ objeto
Confirma la transacción activa actual en la sesión.
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 789 790 791 792 793 794 795 |
# Archivo 'lib/mongo/session.rb', línea 724 def commit_transaction( = 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 ||= {} 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 = [conformidad_de_lectura] || [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() ) 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..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.
898 899 900 |
# Archivo 'lib/mongo/session.rb', línea 898 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.
150 151 152 |
# Archivo 'lib/mongo/session.rb', línea 150 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.
158 159 160 |
# Archivo 'lib/mongo/session.rb', línea 158 def dirty? @server_session&.dirty? end |
#end_session ⇒ nil
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.
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
# Archivo 'lib/mongo/session.rb', línea 385 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.
255 256 257 |
# Archivo 'lib/mongo/session.rb', línea 255 def ¿terminado? !!@se terminó end |
#¿explícito? ⇒ true, false
¿Es esta una sesión explícita (es decir, creado por el usuario).
190 191 192 |
# Archivo 'lib/mongo/session.rb', línea 190 def explicit? !implicit? end |
#¿implícito? ⇒ true, false
¿Esta sesión es implícita (no creada por el usuario)?.
178 179 180 |
# Archivo 'lib/mongo/session.rb', línea 178 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.
890 891 892 |
# Archivo 'lib/mongo/session.rb', línea 890 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.
1307 1308 1309 |
# Archivo 'lib/mongo/session.rb', línea 1307 def adentro_con_transacción? @inside_with_transaction end |
#inspect ⇒ String
Obtén una string formateada para usar en la inspección.
363 364 365 |
# Archivo 'lib/mongo/session.rb', línea 363 def inspeccionar "#<Mongo::Session:0x#{object_id} session_id=#{session_id} options=#{@options}>" end |
#materialize_if_needed ⇒ 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.
Si aún no está configurado, rellene el server_session de un objeto de sesión sacando una sesión del grupo de sesiones.
1237 1238 1239 1240 1241 1242 1243 1244 1245 |
# Archivo 'lib/mongo/session.rb', línea 1237 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.
1248 1249 1250 1251 1252 |
# Archivo 'lib/mongo/session.rb', línea 1248 def ¿materializado? propagar Error::SessionEnded si ¿terminado? !@server_session.nil? end |
#next_txn_num ⇒ Integer
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.
1263 1264 1265 1266 1267 |
# Archivo 'lib/mongo/session.rb', línea 1263 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.
932 933 934 935 936 937 |
# Archivo 'lib/mongo/session.rb', línea 932 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.
915 916 917 918 919 920 921 922 923 |
# Archivo 'lib/mongo/session.rb', línea 915 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.
1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 |
# Archivo 'lib/mongo/session.rb', línea 1197 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.
210 211 212 |
# Archivo 'lib/mongo/session.rb', línea 210 def retry_reads? Cliente.[:retry_reads] != false end |
#retry_writes? ⇒ true, false
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?
225 226 227 |
# Archivo 'lib/mongo/session.rb', línea 225 def ¿retry_writes? !!Cliente.[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.
1148 1149 1150 1151 1152 |
# Archivo 'lib/mongo/session.rb', línea 1148 def revertir_a_transacción_inicial! return a menos que within_states?(TRANSACTION_IN_PROGRESS_STATE) @state = STARTING_TRANSACTION_STATE end |
#session_id ⇒ BSON::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.
267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# Archivo 'lib/mongo/session.rb', línea 267 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.
134 135 136 |
# Archivo 'lib/mongo/session.rb', línea 134 def snapshot? !![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.
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 701 702 703 704 705 706 707 |
# Archivo 'lib/mongo/session.rb', línea 660 def start_transaction( = nulo) verifica_transacciones_soportadas! si Lint.validate_read_concern_option([: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( || {}) 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.
878 879 880 |
# Archivo 'lib/mongo/session.rb', línea 878 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.
1112 1113 1114 1115 1116 1117 1118 1119 |
# Archivo 'lib/mongo/session.rb', línea 1112 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_num ⇒ Integer
Obtén el número de transacción actual.
1277 1278 1279 1280 1281 |
# Archivo 'lib/mongo/session.rb', línea 1277 def txn_num propagar Error::SessionEnded si ¿terminado? @server_session.txn_num end |
#txn_options ⇒ Hash
en esta sesión.
166 167 168 |
# Archivo 'lib/mongo/session.rb', línea 166 def @txn_options or propagar ArgumentError, 'No hay ninguna transacción activa' end |
#txn_read_concern ⇒ encriptada
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.
Obtenga el nivel de consistencia de lectura que utilizará la sesión al iniciar una transacción.
Esto es un hash de estilo de controlador con claves de guion bajo.
1322 1323 1324 1325 |
# Archivo 'lib/mongo/session.rb', línea 1322 def txn_read_concern # El nivel de consistencia de lectura se hereda del cliente, pero no de la base de datos ni de la colección. [:read_concern] || @client.read_concern end |
#txn_read_preference ⇒ Hash
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.
240 241 242 243 244 245 |
# Archivo 'lib/mongo/session.rb', línea 240 def preferencia_de_lectura_txn rp = [: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.
945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 |
# Archivo 'lib/mongo/session.rb', línea 945 def unpin(Conexión = nulo) # Idempotente: si no hay un estado anclado que borrar, no hagas nada. Anidado # unpin_maybe handlers (e.g. in BulkWrite#execute_operation wrapping an # Ejecución de OpMsg que ya llama a unpin_maybe en su propio do_execute) # puede llamar a este método dos veces para el mismo error; comprobando la conexión # volver a la piscina por segunda vez se levantaría de la piscina. return si @pinned_server.nil? && @pinned_connection.nil? && @pinned_connection_global_id.nil? @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).
978 979 980 981 982 983 984 985 986 987 988 |
# Archivo 'lib/mongo/session.rb', línea 978 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).
1158 1159 1160 1161 1162 1163 1164 1165 |
# Archivo 'lib/mongo/session.rb', línea 1158 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.
1180 1181 1182 1183 1184 |
# Archivo 'lib/mongo/session.rb', línea 1180 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.
1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 |
# Archivo 'lib/mongo/session.rb', línea 1131 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
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.
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 620 621 622 623 624 625 626 |
# Archivo 'lib/mongo/session.rb', línea 458 def with_transaction( = nulo) @inside_with_transaction = true @with_transaction_timeout_ms = &.dig(:timeout_ms) || @options[:default_timeout_ms] || @client.timeout_ms @with_transaction_deadline = calculate_with_transaction_deadline() # Cuando CSOT está habilitado, tenemos una fecha límite definida por el cliente; de lo contrario # volver a la fecha límite por defecto, 120 segundos. fecha límite = @with_transaction_deadline || (Utils.monotonic_time + 120) 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 = {} [conformidad_de_lectura] = [conformidad_de_lectura] si start_transaction() 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() 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 = caso v = [conformidad_de_lectura] cuando Nivel de confirmación de escritura (write concern)::Base v. cuando nulo {} else v end [conformidad_de_lectura] = .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 |