= Chapter 1: Replica Set Transactions == introduction * snapshot isolation * all-or-nothing execution * = ACID Data Guarantess en multiples comandos y múltiples documentos a través de 1 o varias colecciones -> transacciones * posible añadir a quien lo requiera, no efecta a "performance" si no es necesario * multi-document transactions * transacciones funcionan a través de los replica sets * entre shared clusters a partir de MongoDB 4.2 == Transaction Considerations * WiredTiger cache puede retirar snapshots y abortar transacciones si se llega a los límites * tecnología de snapshots para asegurar las transacciones * MongoDB tira atrás cualquier transacción que dure más de 60 segundos, haciendo un roll back * aunque no hay límite, no se deberían de modificar más de 1000 documentos en una transacción * si afecta a más documentos, el desarrollador debería separarlo en lotes * hay que contemplar la recogida de las excepciones por el exceso de tiempo (error transitorio de la red, elección?) * Operaciones DDL (crear indice, borrar coleccion) -> bloqueo de transacciones en el "namespace" == Write Conflicts * si no se obtiene el "lock" para realizar la operación de escritura, la operación se aborta * 2 transacciones sobre el mismo documento, la segunda es abortada para evitar deadlocks * no afecta a las operaciones de lectura == Transactions Use Cases * se estima que el 80%-90% de las aplicaciones no necesitan el uso de transacciones * pero no están acostumbrados a este nuevo tipo de paradigma o siguen con la inercia de las BBDD relacionales * o están preocupados por si en un futuro si que lo necesitan * MongoDB se encarga de las transacciones a multi-documento automaticamente == Abort vs Commit * agresiva política para evitar los deadlock * el desarrollador ha de tener control sobre operaciones abortadas * errores en commit * se reintentan 1 vez desde el server * después se coge la excepción y se trata (con repeticiones o abortándola) def run_transaction_and_retry_commit(client): with client.start_session() as s: s.start_transaction() collection_one.insert_one(doc1, session=s) collection_two.insert_one(doc2, session=s) while True: try: s.commit_transaction() break except (OperationFailure, ConnectionFailure) as exc: if exc.has_error_label("UnknownTransactionCommitResult"): print("Unknown commit result, retrying...") continue raise while True: try: return run_transaction_and_retry_commit(client) except (OperationFailure, ConnectionFailure) as exc: if exc.has_error_label("TransientTransactionError"): print("Transient transaction error, retrying...") continue raise