sql >> Base de Datos >  >> NoSQL >> MongoDB

Una descripción general de las transacciones ACID de documentos múltiples en MongoDB y cómo usarlas

Los sistemas de bases de datos tienen el mandato de garantizar la consistencia e integridad de los datos, especialmente cuando se trata de datos críticos. Estos aspectos se aplican a través de transacciones ACID en MongoDB. Una transacción ACID debe cumplir con algunas reglas definidas para la validez de los datos antes de realizar cualquier actualización en la base de datos; de lo contrario, debe cancelarse y no se deben realizar cambios en la base de datos. Todas las transacciones de la base de datos se consideran como una única operación lógica y, durante el tiempo de ejecución, la base de datos se pone en un estado inconsistente hasta que se confirman los cambios. Las operaciones que cambian con éxito el estado de la base de datos se denominan transacciones de escritura, mientras que las que no actualizan la base de datos sino que solo recuperan datos se denominan transacciones de solo lectura. ACID es un acrónimo de Atomicidad, Consistencia, Aislamiento y Durabilidad.

Una base de datos es un recurso compartido al que pueden acceder diferentes usuarios en momentos diferentes o al mismo tiempo. Por esta razón, pueden ocurrir transacciones simultáneas y, si no se gestionan bien, pueden provocar bloqueos del sistema, fallas de hardware, bloqueos, rendimiento lento de la base de datos o repetición en la ejecución de la misma transacción.

¿Qué son las reglas ACID?

Todos los sistemas de bases de datos deben cumplir con las propiedades ACID para garantizar la integridad de los datos.

Atomicidad

Una transacción se considera como una sola unidad de operación que puede tener éxito o fallar por completo. Una transacción no se puede ejecutar parcialmente. Si alguna condición de consulta de una transacción falla, toda la transacción fallará por completo y la base de datos permanecerá sin cambios. Por ejemplo, si desea transferir fondos de la cuenta X a Y, aquí hay dos transacciones, la primera es para retirar fondos de X y la segunda es para registrar los fondos en Y. Si la primera transacción falla, todo el la transacción será abortada

Coherencia

Cuando se emite una operación, antes de la ejecución, la base de datos está en un estado consistente y debe permanecer así después de cada transacción. Incluso si hay una actualización, la transacción siempre debe llevar la base de datos a un estado válido, manteniendo las invariantes de la base de datos. Por ejemplo, no puede eliminar una clave principal a la que se ha hecho referencia como clave externa en otra colección. Todos los datos deben cumplir con las restricciones definidas para evitar la corrupción de datos por una transacción ilegal.

Aislamiento

Múltiples transacciones que se ejecutan simultáneamente se ejecutan sin afectarse entre sí y su resultado debería ser el mismo si se ejecutaran secuencialmente. Cuando dos o más transacciones modifican los mismos documentos en MongoDB, puede haber un conflicto. La base de datos detectará un conflicto inmediatamente antes de que se confirme. La primera operación para adquirir un bloqueo en el documento continuará mientras que la otra fallará y se presentará un mensaje de error de conflicto.

Durabilidad

Esto dicta que, una vez que se ha confirmado la transacción, los cambios deben mantenerse en todo momento, incluso en caso de falla del sistema, por ejemplo, debido a cortes de energía o desconexión de Internet.

Transacciones MongoDB ACID

MongoDB es una base de datos NoSQL basada en documentos con un esquema flexible. Las transacciones no son operaciones que deban ejecutarse para cada operación de escritura, ya que incurren en un mayor costo de rendimiento en comparación con las escrituras de un solo documento. Con una estructura basada en documentos y un modelo de datos desnormalizados, habrá una necesidad mínima de transacciones. Dado que MongoDB permite la incrustación de documentos, no necesariamente necesita usar una transacción para cumplir con una operación de escritura.

MongoDB versión 4.0 brinda compatibilidad con transacciones de documentos múltiples solo para implementaciones de conjuntos de réplicas y probablemente la versión 4.2 ampliará la compatibilidad con implementaciones fragmentadas (según sus notas de lanzamiento).

Ejemplo de una transacción:

Asegúrese primero de tener un conjunto de réplicas. Suponiendo que tiene una base de datos llamada aplicación y una colección de usuarios en Mongo Shell, ejecute los siguientes comandos:

$mongos y debería ver algo como nombre de usuario:PRIMARY>

$use app

$db.users.insert([{_id:1, name: ‘Brian’}, {_id:2, name: ‘Sheila’}, {_id:3, name: ‘James’}])

Necesitamos iniciar una sesión para nuestra transacción:

$db.getMongo().startSession() and you should see something like 

session { "id" : UUID("dcfa8de5-627d-3b1c-a890-63c9a355520c") }

Usando esta sesión podemos agregar más usuarios usando una transacción con los siguientes comandos 

$session.startTransaction()

session.getDatabase(‘app’).users.insert({_id:4, name:  ‘Hitler’})

Se le presentará WriteResult({“nInsterted”:2})

La transacción aún no se ha confirmado y el $db.users.find({}) normal nos dará solo los usuarios guardados previamente. Pero si ejecutamos el 

$session.getDatabase(“app”).users.find()

el último registro agregado estará disponible en los resultados devueltos. Para confirmar esta transacción, ejecutamos el siguiente comando

$session.commitTransaction()

La modificación de la transacción se almacena en la memoria, por lo que incluso después de la falla, los datos estarán disponibles en la recuperación.

Transacciones ACID de múltiples documentos en MongoDB

Estas son operaciones de instrucciones múltiples que deben ejecutarse secuencialmente sin afectarse entre sí. Para el ejemplo anterior, podemos crear dos transacciones, una para agregar un usuario y otra para actualizar un usuario con un campo de edad. Es decir,

$session.startTransaction()

   db.users.insert({_id:6, name “Ibrahim”})

   db.users.updateOne({_id:3 , {$set:{age:50}}})

session.commit_transaction()

Las transacciones se pueden aplicar a operaciones contra múltiples documentos contenidos en una o varias colecciones/bases de datos. Los cambios debidos a transacciones de documentos no afectan el rendimiento de las cargas de trabajo no relacionadas o no las requieren. Hasta que se confirma la transacción, las escrituras no confirmadas no se replican en los nodos secundarios ni se pueden leer fuera de las transacciones.

Mejores prácticas para transacciones MongoDB

Las transacciones de varios documentos solo se admiten en el motor de almacenamiento WiredTiger. Como se mencionó anteriormente, muy pocas aplicaciones requerirían transacciones y, de ser así, deberíamos intentar que sean breves. De lo contrario, para una sola transacción ACID, si intenta realizar una cantidad excesiva de operaciones, puede generar una alta presión en el caché de WiredTiger. La memoria caché siempre se dicta para mantener el estado para todas las escrituras posteriores desde que se creó la instantánea más antigua. Esto significa que las escrituras nuevas se acumularán en la memoria caché a lo largo de la transacción y se eliminarán solo después de que las transacciones que se ejecutan actualmente en instantáneas antiguas se confirmen o anulen. Para obtener el mejor rendimiento de la base de datos en la transacción, los desarrolladores deben considerar:

  1. Siempre modifique una pequeña cantidad de documentos en una transacción. De lo contrario, deberá dividir la transacción en diferentes partes y procesar los documentos en diferentes lotes. Como máximo, procese 1000 documentos a la vez.
  2. Las excepciones temporales, como la espera para elegir problemas de red primarios y transitorios, pueden provocar el aborto de la transacción. Los desarrolladores deben establecer una lógica para volver a intentar la transacción si se presentan los errores definidos.
  3. Configure la duración óptima para la ejecución de la transacción a partir de los 60 segundos predeterminados proporcionados por MongoDB. Además, emplee la indexación para que pueda permitir un acceso rápido a los datos dentro de la transacción. También tiene la flexibilidad de ajustar la transacción para abordar los tiempos de espera al dividirla en lotes que permitan su ejecución dentro de los límites de tiempo.
  4. Descomponga su transacción en un pequeño conjunto de operaciones para que se ajuste a las restricciones de tamaño de 16 MB. De lo contrario, si la operación junto con la descripción del registro de operaciones superan este límite, la transacción se cancelará.
  5. Todos los datos relacionados con una entidad deben almacenarse en una única estructura de documento rica. Esto es para reducir la cantidad de documentos que se almacenarán en caché cuando se cambien diferentes campos.

Limitaciones de Transacciones

  1. No puede crear ni soltar una colección dentro de una transacción.
  2. Las transacciones no pueden realizar escrituras en una colección limitada
  3. Las transacciones toman mucho tiempo para ejecutarse y de alguna manera pueden ralentizar el rendimiento de la base de datos.
  4. El tamaño de la transacción está limitado a 16 MB, lo que requiere dividir cualquier transacción que tienda a exceder este tamaño en transacciones más pequeñas.
  5. Sujetar una gran cantidad de documentos a una transacción puede ejercer una presión excesiva sobre el motor de WiredTiger y, dado que se basa en la capacidad de instantáneas, habrá una retención de grandes operaciones sin vaciar en la memoria. Esto representa un costo de rendimiento en la base de datos.

Conclusión

MongoDB versión 4.0 introdujo el soporte de transacciones de documentos múltiples para conjuntos de réplicas como una característica para mejorar la integridad y consistencia de los datos. Sin embargo, hay muy pocas aplicaciones que requieran transacciones al usar MongoDB. Existen limitaciones en contra de esta función que la hacen considerablemente un poco inmadura en lo que respecta al concepto de transacciones. Por ejemplo, las transacciones para un clúster fragmentado no son compatibles y no pueden superar el límite de tamaño de 16 MB. El modelado de datos proporciona una mejor estructura para reducir las transacciones en su base de datos. A menos que se trate de casos especiales, será una mejor práctica evitar transacciones en MongoDB.