{"id":10953,"date":"2021-03-23T01:24:55","date_gmt":"2021-03-23T08:24:55","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=10953"},"modified":"2024-01-26T19:17:43","modified_gmt":"2024-01-27T03:17:43","slug":"distributed-multi-document-acid-transactions","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/distributed-multi-document-acid-transactions\/","title":{"rendered":"C\u00f3mo implementamos las transacciones ACID multidocumento distribuidas en Couchbase"},"content":{"rendered":"<p><span style=\"font-weight: 400\"><a href=\"https:\/\/www.couchbase.com\/blog\/es\/transactions\/\">Transacciones ACID<\/a> son imprescindibles cuando se tienen requisitos estrictos de coherencia de datos en la aplicaci\u00f3n. Los costes de ejecutar transacciones en sistemas distribuidos pueden crear r\u00e1pidamente cuellos de botella a escala. En este art\u00edculo, te daremos una visi\u00f3n general de algunos de los retos a los que se enfrentan las bases de datos NoSQL y NewSQL. Luego, profundizaremos en c\u00f3mo Couchbase implement\u00f3 un modelo de transacciones distribuidas escalable sin coordinaci\u00f3n central y sin punto \u00fanico de fallo. Adem\u00e1s, tambi\u00e9n dar\u00e9 una breve visi\u00f3n general de c\u00f3mo se ve el soporte para transacciones en N1QL en Couchbase 7.0.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Se han omitido algunos detalles menores en aras de la simplicidad.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-weight: 400\">Transacciones relacionales vs NewSQL vs NoSQL<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Antes de empezar a explicar c\u00f3mo Couchbase implement\u00f3 el soporte para transacciones, necesito explicar primero las caracter\u00edsticas inherentes de la atomicidad en bases de datos relacionales y NoSQL (usando modelos de datos semi-estructurados como JSON):<\/span><\/p>\n<p>&nbsp;<\/p>\n<h3><span style=\"font-weight: 400\">Atomicidad en RDBMS<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Supongamos que necesita guardar un nuevo usuario en la base de datos. Naturalmente, como tiene muchas otras tablas asociadas, insertar un usuario tambi\u00e9n requerir\u00e1 inserciones en muchas otras tablas:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-10954\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Picture1.png\" alt=\"Transactions on Relational\" width=\"750\" height=\"419\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Picture1.png 968w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Picture1-300x168.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Picture1-768x429.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Picture1-20x11.png 20w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Dado que el modelo relacional te obliga a almacenar todo en \"cajas\" y a dividir tus datos en peque\u00f1os trozos, a\u00f1adir un nuevo usuario siempre debe ejecutarse dentro de un contexto transaccional. De lo contrario, si una de tus inserciones falla, tu usuario acabar\u00e1 a medias. Observe c\u00f3mo un RDBMS depende en gran medida de las transacciones, ya que las aplicaciones son mucho m\u00e1s complejas que cuando se dise\u00f1\u00f3 originalmente el modelo relacional all\u00e1 por los a\u00f1os setenta.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Por suerte, como estas bases de datos est\u00e1n dise\u00f1adas para ejecutarse en un \u00fanico nodo, puede utilizar un coordinador de transacciones central para consignar los datos de una vez sin que ello afecte al rendimiento. <\/span><\/p>\n<p>&nbsp;<\/p>\n<h3><span style=\"font-weight: 400\">Atomicidad en NewSQL<\/span><\/h3>\n<p><span style=\"font-weight: 400\">En el lado NewSQL (relacional distribuida), las cosas son un poco m\u00e1s complicadas. Como la mayor\u00eda de estas bases de datos reutilizan el modelo relacional, los datos de tu entidad (o <\/span><a href=\"https:\/\/martinfowler.com\/bliki\/DDD_Aggregate.html\"><span style=\"font-weight: 400\">ra\u00edz agregada<\/span><\/a><span style=\"font-weight: 400\">) tiende a repartirse entre varios nodos.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-10966\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Screen-Shot-2021-03-05-at-2.46.28-PM-1024x415.png\" alt=\"atomicity in newsql\" width=\"656\" height=\"266\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-05-at-2.46.28-PM-1024x415.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-05-at-2.46.28-PM-300x122.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-05-at-2.46.28-PM-768x311.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-05-at-2.46.28-PM-20x8.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-05-at-2.46.28-PM.png 1122w\" sizes=\"auto, (max-width: 656px) 100vw, 656px\" \/><\/p>\n<p><span style=\"font-weight: 400\">En la imagen de arriba, si necesitamos cargar el usuario en memoria, primero tendr\u00edamos que obtener el usuario del Servidor 1, luego cargar la asociaci\u00f3n entre usuarios y roles en el Servidor 2 y finalmente cargar el rol de destino desde el Servidor 3. Esta simple operaci\u00f3n requiere que los datos viajen al menos dos veces por la red, lo que en \u00faltima instancia limitar\u00e1 su rendimiento de lectura. En un escenario real, un usuario tiene muchas m\u00e1s tablas asociadas a \u00e9l. Esta es la raz\u00f3n por la que la relacional distribuida todav\u00eda no es pr\u00e1ctica cuando se necesita leer\/escribir lo m\u00e1s r\u00e1pido posible.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Puedes intentar minimizar los problemas anteriores limitando el tama\u00f1o de tu cl\u00faster, confiando mucho en los \u00edndices para rastrear todas las relaciones, o mediante algunas t\u00e9cnicas de fragmentaci\u00f3n para mantener todos los datos relacionados en el mismo nodo (lo cual es dif\u00edcil de implementar en la pr\u00e1ctica). Los dos \u00faltimos enfoques, aunque est\u00e9n bien implementados, consumir\u00e1n importantes recursos de la base de datos para ser gestionados adecuadamente.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Las transacciones ACID en bases de datos NewSQL requieren m\u00e1s coordinaci\u00f3n que en NoSQL, ya que los datos relacionados con una entidad se dividen en m\u00faltiples tablas que pueden vivir en diferentes nodos. El modelo relacional, tal y como lo utilizamos hoy en d\u00eda, requiere transacciones para la mayor\u00eda de las escrituras, actualizaciones y eliminaciones en cascada. La coordinaci\u00f3n adicional que requiere la arquitectura NewSQL tiene el coste de reducir el rendimiento de las aplicaciones que requieren operaciones de baja latencia.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h3><span style=\"font-weight: 400\">Atomicidad en las bases de datos de documentos<\/span><\/h3>\n<p><span style=\"font-weight: 400\">El uso de datos semiestructurados como JSON puede reducir dr\u00e1sticamente el n\u00famero de \"uniones entre nodos\" y, por tanto, mejorar el rendimiento de lectura y escritura sin necesidad de recurrir en exceso a la indexaci\u00f3n. Esta fue una de las principales conclusiones del estudio <\/span><a href=\"https:\/\/www.allthingsdistributed.com\/files\/amazon-dynamo-sosp2007.pdf\"><span style=\"font-weight: 400\">Papel Dynamo<\/span><\/a><span style=\"font-weight: 400\"> (publicado por primera vez hace ~13 a\u00f1os) que fue el<\/span><span style=\"font-weight: 400\"> catalizador para crear las bases de datos NoSQL tal y como las conocemos hoy.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Otra caracter\u00edstica interesante de un modelo de datos semiestructurado es que es menos transaccional, ya que podr\u00edan caber todos los datos del usuario en un solo documento:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-10956\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/JSON-Denis.png\" alt=\"atomicity nosql\" width=\"332\" height=\"399\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/JSON-Denis.png 854w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/JSON-Denis-250x300.png 250w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/JSON-Denis-768x922.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/JSON-Denis-300x360.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/JSON-Denis-17x20.png 17w\" sizes=\"auto, (max-width: 332px) 100vw, 332px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Como se puede ver en la imagen superior, las preferencias y roles de los usuarios caben f\u00e1cilmente dentro de un \"Documento de Usuario\", por lo que no es necesaria una transacci\u00f3n para insertar o actualizar un usuario ya que la operaci\u00f3n es at\u00f3mica. O insertamos el documento o falla toda la operaci\u00f3n. Lo mismo es v\u00e1lido para muchos otros casos de uso comunes: carros de la compra, productos, estructuras de \u00e1rbol, y <\/span><a href=\"https:\/\/martinfowler.com\/bliki\/DDD_Aggregate.html\"><span style=\"font-weight: 400\">ra\u00edces agregadas <\/span><\/a><span style=\"font-weight: 400\">en general.<\/span><\/p>\n<p><span style=\"font-weight: 400\">En la mayor\u00eda de las aplicaciones que utilizan bases de datos de documentos, 90% de las operaciones transaccionales corresponder\u00e1n a esta categor\u00eda de documento \u00fanico. Pero... \u00bfqu\u00e9 pasa con los otros 10%? Bueno, para esas necesitaremos soporte transaccional multi-documento, que ha sido a\u00f1adido en Couchbase desde la versi\u00f3n 6.5 y es el foco principal de este art\u00edculo.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Aqu\u00ed tienes una presentaci\u00f3n sobre transacciones que se realiz\u00f3 en Couchbase Connect 2020. Matt Ingenthron te da una explicaci\u00f3n de cu\u00e1ndo y por qu\u00e9 podr\u00edas necesitar transacciones ACID multi-documento:<\/span><\/p>\n<h6 style=\"text-align: center\"><span style=\"font-weight: 400\">Vea la versi\u00f3n completa en <\/span><a href=\"https:\/\/www.youtube.com\/watch?v=2fsZVe2cT3M&amp;ab_channel=Couchbase\"><span style=\"font-weight: 400\">https:\/\/www.youtube.com\/watch?v=2fsZVe2cT3M&amp;ab_channel=Couchbase<\/span><\/a><\/h6>\n<p>&nbsp;<\/p>\n<h3><span style=\"font-weight: 400\">Transcripci\u00f3n del v\u00eddeo<\/span><\/h3>\n<details>\n<summary>Haga clic para leer la transcripci\u00f3n completa.<\/summary>\n<p><span style=\"font-weight: 400\">Vamos a hablar de c\u00f3mo se aplica esto a un ejemplo ficticio, pero tal vez algo realista, de un modelo de documento para un sistema Couchbase. As\u00ed que hemos recaudado algo de dinero, y vamos a construir un juego de rol multijugador masivo en l\u00ednea (un MMORPG), con jugadores y monstruos. As\u00ed que necesitamos un modelo de datos.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">Vamos a tener jugadores que luchan contra monstruos y, a continuaci\u00f3n, sobre la base de esa lucha, ganar o perder, van a. Si ganan, van a conseguir un arma, si pierden, eh, pierden algunos puntos de golpe para que nadie pueda morir. Siempre se puede volver a la vida, siempre se puede encontrar otro d\u00eda. Pero sus jugadores luchar contra monstruos, y tenemos nuestra versi\u00f3n 1.0 construido. \u00a1Genial! Bien, conseguimos nuestra financiaci\u00f3n, conseguimos nuestra 1.0 construida.<\/span><\/p>\n<p><span style=\"font-weight: 400\">El problema es que nos olvidamos de la parte multijugador masivo. No hay juego colaborativo. No puedo tener m\u00faltiples jugadores luchando contra el mismo monstruo. As\u00ed que tengo que arreglar eso, \u00bfverdad? As\u00ed que vamos a lanzar una nueva versi\u00f3n. As\u00ed que los jugadores van a seguir luchando contra monstruos y ganando armas.<\/span><\/p>\n<p><span style=\"font-weight: 400\">As\u00ed que lanzamos nuestra versi\u00f3n 2.0, y en la versi\u00f3n 2.0 los jugadores pueden luchar juntos contra los monstruos. Puedo coordinar con mis amigos, podr\u00edamos ir a buscar un monstruo, y podemos matar a ese monstruo.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">Pero dejamos un error ah\u00ed. Es posible que varios jugadores asesten el golpe mortal y la raz\u00f3n de que eso sea un problema es que los jugadores del juego se dan cuenta. En lugar de luchar contra un monstruo juntos hasta la muerte, lo que hacen es, ellos, en este mundo multijugador masivo, luchar hasta casi la muerte, y luego un grupo de jugadores se reunir\u00e1n, y todos ellos asestar\u00e1n el golpe mortal o muchos asestar\u00e1n el golpe mortal al mismo tiempo.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">El problema es que ganan objetos, ganan m\u00faltiples objetos, y como los objetos tienen rareza, y si no tienes una cierta cantidad de rareza para un objeto, el juego no es muy interesante. Este error ha permitido que existan demasiados objetos en el mundo, y los jugadores se pasan el tiempo pirateando el juego, y luego se aburren y lo abandonan. Tenemos que mantener la jugabilidad interesante.<\/span><\/p>\n<p><span style=\"font-weight: 400\">As\u00ed que pensemos en esto. \u00bfC\u00f3mo podemos arreglarlo? Creo que lo que tendremos que hacer es probablemente introducir un arreglo. Seguiremos permitiendo que jugadores y monstruos, varios jugadores luchen contra un monstruo. Pero lo que vamos a hacer es tomar uno de esos trucos que tenemos, vamos a tomar <\/span><a href=\"https:\/\/docs.couchbase.com\/java-sdk\/current\/howtos\/concurrent-document-mutations.html\"><span style=\"font-weight: 400\">Couchbase CAS <\/span><\/a><span style=\"font-weight: 400\">Operaciones.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Con el <\/span><a href=\"https:\/\/docs.couchbase.com\/java-sdk\/current\/howtos\/concurrent-document-mutations.html\"><span style=\"font-weight: 400\">Operaci\u00f3n CAS<\/span><\/a><span style=\"font-weight: 400\"> lo que ocurre es que ahora varios jugadores est\u00e1n luchando contra ese monstruo, reduciendo sus puntos de vida hasta que llega a cero. Pero s\u00f3lo uno de esos jugadores ser\u00e1 capaz de asestar el golpe mortal a ese monstruo y ganar un objeto.<\/span><\/p>\n<p><span style=\"font-weight: 400\">As\u00ed que la forma en que esto funciona es si dos jugadores est\u00e1n tratando de dar ese golpe mortal, la aplicaci\u00f3n <\/span><span style=\"font-weight: 400\">servidor que est\u00e1 manejando la solicitud va a tratar de modificar el documento. Tiene que recoger una peque\u00f1a pieza de informaci\u00f3n opaca que llamamos el<\/span><a href=\"https:\/\/docs.couchbase.com\/java-sdk\/current\/howtos\/concurrent-document-mutations.html\"><span style=\"font-weight: 400\"> CAS (siglas de Check And Set)<\/span><\/a><span style=\"font-weight: 400\">y eso significa que si ese opaque no coincide, entonces los documentos ya han sido modificados, por lo que hay que reintentar esa operaci\u00f3n. En el escenario de que dos actores dentro del sistema est\u00e1n tratando de agarrar ese documento al mismo tiempo, lo que queremos es que uno tenga \u00e9xito y otro falle, y el CAS nos dar\u00e1 eso de una manera muy eficiente.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Sacamos ese truco, introducimos operaciones CAS, se arregla el fallo, la jugabilidad es ahora mucho m\u00e1s interesante y la 2.1 lo hace realmente bien, as\u00ed que estupendo.<\/span><\/p>\n<p><span style=\"font-weight: 400\">As\u00ed que ahora vamos a intentar un , eh, queremos seguir adelante, queremos hacer las cosas m\u00e1s interesantes. Imagina ahora que introduzco otra caracter\u00edstica: \"Los jugadores pueden seguir luchando juntos contra los monstruos, pero tienen que hacerlo fuera de la ciudad. As\u00ed que tienen que estar fuera de la muralla de la ciudad donde est\u00e1n los jugadores, y si entran en la ciudad, har\u00e1n comercio en un bizarro\"<\/span><\/p>\n<p><span style=\"font-weight: 400\">Esto funciona muy bien al principio, pero luego los jugadores se dan cuenta de algo.<\/span><\/p>\n<p><span style=\"font-weight: 400\">As\u00ed que imagina jugador1, tengo que recuperar el documento para jugador1. Luego tengo que recuperar el documento para el jugador2. Luego tengo que mover la espada del jugador1 al jugador2, eso es muy f\u00e1cil de hacer en la l\u00f3gica de la aplicaci\u00f3n, y luego voy a almacenar ese cambio de nuevo al sistema con la operaci\u00f3n CAS, y luego voy a almacenar el otro cambio de nuevo, \u00bfverdad? Suena como que va a ser grande. Excepto que hay un error.<\/span><\/p>\n<p><span style=\"font-weight: 400\">El error aqu\u00ed es que mis jugadores pueden empezar un intercambio y luego desconectarse, y entonces los objetos que podr\u00edamos querer que fueran raros no van a ser raros. Pueden ser duplicados dentro del sistema.<\/span><\/p>\n<p><span style=\"font-weight: 400\">En los juegos de rol multijugador masivos en l\u00ednea, se llama \"Dup Bug\". Si vas a Google y buscas \"Dup Bug\", encontrar\u00e1s un mont\u00f3n de escenarios.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Aqu\u00ed hay uno de hace s\u00f3lo un par de semanas, donde Final Fantasy Crystal Chronicles en Switch tuvo que ser parcheado debido a un bug Dup. Y luego hab\u00eda uno s\u00f3lo unos d\u00edas antes de que, esto es de un blog donde un blogger juego mostrando a la gente c\u00f3mo utilizar este glitch dup para recuperar... para obtener art\u00edculos adicionales dentro del juego.<\/span><\/p>\n<p><span style=\"font-weight: 400\">As\u00ed que tenemos que arreglar este fallo. \u00bfC\u00f3mo vamos a hacerlo? Bueno, vamos a echar mano de nuestra bolsa de trucos de Couchbase.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Vamos a introducir las transacciones Couchbase. El modo de juego es casi exactamente el mismo. Pero, \u00bfqu\u00e9 vamos a hacer con las transacciones Couchbase? Y esta es la diapositiva donde voy a hablar un poco sobre el c\u00f3digo.<\/span><\/p>\n<\/details>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-weight: 400\">Transacciones ACID distribuidas multidocumento en Couchbase<\/span><\/h2>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400\">Ahora que entiendes c\u00f3mo se comportan las transacciones en diferentes modelos de datos, es hora de profundizar en c\u00f3mo lo hemos implementado en Couchbase y qu\u00e9 nos llev\u00f3 a tomar nuestras decisiones de dise\u00f1o. En primer lugar, vamos a repasar la sintaxis:<\/span><\/p>\n<pre class=\"lang:java decode:true\">transactions.run((ctx) -&gt; {\r\n        \/\/ get the account documents for userA and UserB \t\r\n        TransactionJsonDocument userA = ctx.getOrError(collection, \"userA\");\r\n        JsonObject userAContent = userA.contentAsObject();\r\n        int userABalance = userAContent.getInt(\"account_balance\");\r\n        TransactionJsonDocument userB = ctx.getOrError(collection, \"Beth\"); \r\n        JsonObject userBContent = userB.contentAsObject();\r\n        int userBBalance = userBContent.getInt(\"account_balance\");\r\n\r\n        \/\/ if userB has sufficient funds, make the transfer\r\n        if (userBBalance &gt; transferAmount) {\r\n                userAContent.put(\"account_balance\", userABalance + transferAmount);\r\n                ctx.replace(userA, userAContent);\r\n                userBContent.put(\"account_balance\", userBBalance - transferAmount);\r\n                ctx.replace(userB, userBContent);\r\n        }\r\n        else throw new InsufficientFunds();  \r\n});<\/pre>\n<p><span style=\"font-weight: 400\">El ejemplo Java anterior es el ejemplo cl\u00e1sico de c\u00f3mo transferir dinero entre dos clientes.  Observe que hemos decidido utilizar un <\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Anonymous_function\"><span style=\"font-weight: 400\">funci\u00f3n lambda<\/span><\/a><span style=\"font-weight: 400\"> para expresar la transacci\u00f3n. El manejo adecuado de errores puede ser un reto en este escenario y envolver tu transacci\u00f3n con una funci\u00f3n an\u00f3nima permite al SDK Java de Couchbase hacer ese trabajo por ti (es decir, reintentar si algo falla).<\/span><\/p>\n<p><span style=\"font-weight: 400\">Cuando lanzamos por primera vez el soporte para transacciones, intent\u00e1bamos evitar la verborrea. As\u00ed era la sintaxis de transacciones de un competidor:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-10958\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/mdb-transaction-1024x577.png\" alt=\"\" width=\"575\" height=\"324\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/mdb-transaction-1024x577.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/mdb-transaction-300x169.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/mdb-transaction-768x433.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/mdb-transaction-20x11.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/mdb-transaction-1320x744.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/mdb-transaction.png 1411w\" sizes=\"auto, (max-width: 575px) 100vw, 575px\" \/><\/p>\n<p><span style=\"font-weight: 400\">\u00daltimamente, parece que el manejo de transacciones dentro de funciones lambda se est\u00e1 convirtiendo en la norma para las bases de datos NoSQL.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Para aquellos que esperaban que fuera similar a la sintaxis relacional para las transacciones (por ejemplo, comandos SQL BEGIN\/COMMIT\/ROLLBACK), sigue leyendo: \u00a1tambi\u00e9n puedes ejecutar transacciones a trav\u00e9s de N1QL! Ahora, vamos a tratar de entender lo que est\u00e1 sucediendo bajo el cap\u00f3.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h3><span style=\"font-weight: 400\">Revisi\u00f3n de la arquitectura de Couchbase<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Para aquellos que no est\u00e9n familiarizados con la arquitectura de Couchbase, necesito explicar r\u00e1pidamente 4 conceptos importantes antes de seguir adelante:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Couchbase es altamente escalable, puedes pasar f\u00e1cilmente de 1 a 100 nodos en un solo cluster <\/span><span style=\"font-weight: 400\">con el m\u00ednimo esfuerzo<\/span><span style=\"font-weight: 400\">\u00a0<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Los documentos JSON tienen un espacio \"Meta\" llamado <\/span><b>xAttr<\/b> <a href=\"https:\/\/docs.couchbase.com\/java-sdk\/current\/concept-docs\/xattr.html\"><span style=\"font-weight: 400\">donde puede almacenar metadatos sobre su documento<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Dentro de cada Bucket (similar a un esquema en RDBMS), Couchbase distribuye autom\u00e1ticamente los datos en 1024 shards llamados <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/buckets-memory-and-storage\/vbuckets.html\"><span style=\"font-weight: 400\">vBuckets<\/span><\/a><span style=\"font-weight: 400\">. La fragmentaci\u00f3n es totalmente transparente para el desarrollador, y nosotros tambi\u00e9n nos encargamos de la estrategia de fragmentaci\u00f3n. Nuestro algoritmo de fragmentaci\u00f3n (CRC32) garantiza esencialmente que los documentos se distribuyan uniformemente entre estos vBuckets y que no sea necesario volver a fragmentarlos. Los vBuckets se distribuyen uniformemente entre los nodos de su cl\u00faster (por ejemplo, si usted tiene un cl\u00faster de 4 nodos, cada nodo contiene 256 vBuckets).<\/span><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-10961\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/docs-bucket-vBuckets-1024x398.png\" alt=\"\" width=\"506\" height=\"197\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/docs-bucket-vBuckets-1024x398.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/docs-bucket-vBuckets-300x117.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/docs-bucket-vBuckets-768x299.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/docs-bucket-vBuckets-20x8.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/docs-bucket-vBuckets.png 1239w\" sizes=\"auto, (max-width: 506px) 100vw, 506px\" \/><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El SDK del cliente almacena una copia del mapa del cluster, que es un hashmap de los vBuckets y el nodo responsable de ellos. Mediante el hash de la clave del documento, el SDK puede encontrar en qu\u00e9 vBucket deber\u00eda encontrarse el documento. Y gracias al mapa de cl\u00faster puede hablar directamente con el nodo responsable del documento durante las operaciones de guardar\/borrar\/actualizar.\u00a0<\/span><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-10962\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/vbucketToNodeMapping-1024x651.png\" alt=\"bucket to server mapping\" width=\"554\" height=\"352\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/vbucketToNodeMapping-1024x651.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/vbucketToNodeMapping-300x191.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/vbucketToNodeMapping-768x488.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/vbucketToNodeMapping-20x13.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/vbucketToNodeMapping-1320x839.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/vbucketToNodeMapping.png 1482w\" sizes=\"auto, (max-width: 554px) 100vw, 554px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Las opciones de dise\u00f1o anteriores permiten a Couchbase tener una arquitectura sin maestro (tambi\u00e9n denominada maestro\/maestro) en lugar de la tradicional maestro\/esclavo utilizada en otras bases de datos NoSQL. Hay una serie de ventajas de este tipo de arquitectura, pero las relevantes para nosotros ahora son las siguientes:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El SDK ahorra \"un salto de red\" durante las operaciones de inserci\u00f3n\/actualizaci\u00f3n\/eliminaci\u00f3n, ya que sabe d\u00f3nde se encuentra un documento determinado (en la arquitectura maestro\/esclavo hay que preguntar al maestro d\u00f3nde est\u00e1 el documento).<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La base de datos en s\u00ed no tiene un coordinador central, por lo que no existe un \u00fanico punto de fallo. En la pr\u00e1ctica, el cliente act\u00faa indirectamente como un coordinador ligero, ya que sabe exactamente con qu\u00e9 nodo del cl\u00faster debe hablar.<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3><span style=\"font-weight: 400\">Transacciones distribuidas sin coordinador central<\/span><\/h3>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400\">En la arquitectura de Couchbase, cada cliente es responsable de la coordinaci\u00f3n de sus propias transacciones. Naturalmente, todo se hace en el SDK. En pocas palabras, si tienes 100 instancias de tu aplicaci\u00f3n ejecutando transacciones, entonces tienes potencialmente ~100 coordinadores. Estos coordinadores no a\u00f1aden pr\u00e1cticamente ninguna sobrecarga a tu aplicaci\u00f3n, y pronto entender\u00e1s por qu\u00e9.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Si reutilizamos el ejemplo de transferencia de dinero mostrado en nuestro ejemplo de c\u00f3digo y suponemos que los 2 documentos implicados en esta transacci\u00f3n viven en dos nodos diferentes, desde una vista de 1.000 pies la transacci\u00f3n sigue estos pasos:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-10963\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Screen-Shot-2021-03-10-at-4.25.34-PM.png\" alt=\"distribute transaction flow\" width=\"600\" height=\"355\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-10-at-4.25.34-PM.png 762w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-10-at-4.25.34-PM-300x178.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-10-at-4.25.34-PM-20x12.png 20w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<ol>\n<li><span style=\"font-weight: 400\">Cada vBucket tiene un \u00fanico documento responsable del registro de transacciones denominado <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/data\/transactions.html\"><span style=\"font-weight: 400\">Registro de transacciones activas <\/span><\/a><span style=\"font-weight: 400\">(ATR). El ATR puede identificarse f\u00e1cilmente por el\u00a0 <\/span><b>_txn:atr-<\/b> <span style=\"font-weight: 400\">prefijo id. Antes de la primera mutaci\u00f3n del documento ( <span class=\"lang:java decode:true crayon-inline\">ctx.replace(userA, userAContent)<\/span>\u00a0en este caso), se a\u00f1ade una nueva entrada en la carpeta <strong>ATR<\/strong> en el mismo vBucket con el id de la transacci\u00f3n y el estado \"Pendiente\". S\u00f3lo una <strong>ATR<\/strong> por transacci\u00f3n.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El Id de la transacci\u00f3n y el contenido de la primera mutaci\u00f3n, <span class=\"lang:java decode:true crayon-inline\">ctx.replace(userA, userAContent)<\/span>se escenifica en el <\/span><b>xAttrs<\/b><span style=\"font-weight: 400\"> del primer documento (\"usuarioA\").<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El Id de la transacci\u00f3n y el contenido de la segunda mutaci\u00f3n, <span class=\"lang:java decode:true crayon-inline\">ctx.replace(userB, userBContent)<\/span>se escenifica en el <\/span><b>xAttrs<\/b><span style=\"font-weight: 400\"> del segundo documento \"usuarioB\".<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La transacci\u00f3n se marca como \"Comprometida\" en el archivo <strong>ATR<\/strong>. Tambi\u00e9n aprovechamos esta llamada para actualizar la lista de identificadores de documentos implicados en la transacci\u00f3n.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El documento \"usuarioA\" no se ha preparado (se ha eliminado de <strong>xAttrs<\/strong> y sustituye el cuerpo del documento)<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">El documento \"userB\" no est\u00e1 preparado (eliminado de <strong>xAttrs<\/strong> y sustituye el cuerpo del documento)<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">La transacci\u00f3n se marca como \"Completada\" y se elimina de la carpeta <strong>ATR<\/strong><\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400\">Tenga en cuenta que esta aplicaci\u00f3n no est\u00e1 limitada por <\/span><span style=\"font-weight: 400\"><a href=\"https:\/\/docs.couchbase.com\/server\/7.0\/learn\/data\/scopes-and-collections.html\">\u00e1mbitos, colecciones<\/a>,<\/span><span style=\"font-weight: 400\"> o shards (vBuckets). De hecho, puede incluso ejecutar transacciones a trav\u00e9s de m\u00faltiples buckets. Siempre que disponga de permisos suficientes, cualquier documento dentro de su cl\u00faster puede formar parte de una transacci\u00f3n.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Llegados a este punto, supongo que tendr\u00e1 muchas preguntas sobre todas las posibles situaciones de fallo. Vamos a tratar de cubrir aqu\u00ed los temas m\u00e1s importantes. No dudes en dejar comentarios e intentar\u00e9 actualizar el art\u00edculo en consecuencia.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Manipulaci\u00f3n del aislamiento - Vista at\u00f3mica mon\u00f3tona<\/span><\/h3>\n<p><a href=\"https:\/\/jepsen.io\/consistency\"><span style=\"font-weight: 400\">Jepsen<\/span><\/a><span style=\"font-weight: 400\"> tiene un gr\u00e1fico brillante que explica los modelos de coherencia m\u00e1s importantes para las bases de datos:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-10964\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Screen-Shot-2021-03-10-at-4.55.38-PM.png\" alt=\"Consistency Models\" width=\"611\" height=\"434\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-10-at-4.55.38-PM.png 817w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-10-at-4.55.38-PM-300x213.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-10-at-4.55.38-PM-768x545.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-10-at-4.55.38-PM-20x14.png 20w\" sizes=\"auto, (max-width: 611px) 100vw, 611px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Couchbase es compatible con <\/span><b>Leer Comprometidos<\/b><span style=\"font-weight: 400\">\/<\/span><b>Vista at\u00f3mica monot\u00f3nica<\/b><span style=\"font-weight: 400\">\". Pero, \u00bfhasta qu\u00e9 punto es bueno? Bueno.., <\/span><b>Leer Comprometidos<\/b><span style=\"font-weight: 400\"> es la opci\u00f3n por defecto en Postgres, MySQL, MariaDB y muchas otras bases de datos; si nunca has cambiado esa opci\u00f3n, eso es lo que est\u00e1s usando ahora mismo.<\/span><\/p>\n<p><b>Leer Comprometidos<\/b><span style=\"font-weight: 400\"> garantiza que tu aplicaci\u00f3n no pueda leer datos no comprometidos, que es lo que probablemente esperas de tu base de datos, pero la parte interesante aqu\u00ed es c\u00f3mo ocurre realmente el proceso de commit. En las bases de datos relacionales, muy a menudo, hay una coordinaci\u00f3n entre las nuevas versiones de las filas cambiadas en una transacci\u00f3n para tomar el relevo de las anteriores todas al mismo tiempo. Esto se conoce com\u00fanmente como <\/span><b>write-point commit<\/b><span style=\"font-weight: 400\">.<\/span> <span style=\"font-weight: 400\">Para que eso ocurra, <\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Multiversion_concurrency_control\"><span style=\"font-weight: 400\">Control de concurrencia multiversi\u00f3n (MVCC)<\/span><\/a><span style=\"font-weight: 400\"> es necesario. Esto es problem\u00e1tico debido a todo el bagaje que conlleva, por no mencionar lo caro que resulta (en t\u00e9rminos de rendimiento) implementarlo en una base de datos distribuida ACID donde las lecturas\/escrituras r\u00e1pidas son clave.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Otra desventaja de los commits de punto de escritura es que puedes gastar un tiempo valioso sincronizando tu commit pero... ning\u00fan otro hilo lo lee justo despu\u00e9s, desperdiciando todo el esfuerzo gastado con la sincronizaci\u00f3n. Esto ocurre cuando <\/span><b>Vista at\u00f3mica monot\u00f3nica (MAV)<\/b><span style=\"font-weight: 400\"> entra en juego. Se describi\u00f3 por primera vez en el <\/span><a href=\"https:\/\/amplab.cs.berkeley.edu\/wp-content\/uploads\/2013\/10\/hat-vldb2014.pdf\"><span style=\"font-weight: 400\">Transacciones de alta disponibilidad: Virtudes y limitaciones<\/span><\/a><span style=\"font-weight: 400\"> papel y tuvo una gran influencia en nuestro dise\u00f1o.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Con MAV podemos hacer un commit at\u00f3mico en el punto de lectura, lo que mejora significativamente el rendimiento. Veamos c\u00f3mo funciona en la pr\u00e1ctica:<\/span><\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"font-weight: 400\">Lecturas repetibles y vistas at\u00f3micas mon\u00f3tonas<\/span><\/h4>\n<p><span style=\"font-weight: 400\">En nuestro ejemplo de transacci\u00f3n, hay una fracci\u00f3n de tiempo tras <\/span><b>Paso 4<\/b><span style=\"font-weight: 400\"> donde hemos establecido la transacci\u00f3n en el ATR como \"Comprometida\" pero a\u00fan no hemos desagrupado los datos de los documentos involucrados en la transacci\u00f3n. Entonces, \u00bfqu\u00e9 ocurre si otro cliente intenta leer los datos durante este intervalo?<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10992\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Screen-Shot-2021-03-22-at-5.40.37-PM.png\" alt=\"transaction failure scenario\" width=\"673\" height=\"640\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-22-at-5.40.37-PM.png 673w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-22-at-5.40.37-PM-300x285.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-22-at-5.40.37-PM-20x20.png 20w\" sizes=\"auto, (max-width: 673px) 100vw, 673px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Internamente, si por casualidad el SDK encuentra un documento con contenido preparado, tambi\u00e9n leer\u00e1 el ATR para obtener el estado de la transacci\u00f3n. Si el estado es \"Comprometido\", devolver\u00e1 la versi\u00f3n preparada en su lugar. No hay necesidad de sincronizar las escrituras. No hay necesidad de sincronizar escrituras si puedes simplemente resolverlo CUANDO ocurre en tiempo de lectura.\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<h3><span style=\"font-weight: 400\">Durabilidad en una base de datos distribuida<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Una de las tareas m\u00e1s importantes de una base de datos es garantizar que lo que se escribe se queda escrito. Incluso en caso de fallo de un nodo, no se deber\u00eda perder ning\u00fan dato. Esto se logra en Couchbase a trav\u00e9s de dos caracter\u00edsticas: Bucket Replicas y Durability en el SDK.<\/span><\/p>\n<p><a href=\"https:\/\/docs.couchbase.com\/server\/current\/manage\/manage-buckets\/create-bucket.html\"><span style=\"font-weight: 400\">Durante la creaci\u00f3n de su cubo, puede configurar cu\u00e1ntas r\u00e9plicas (copias de seguridad) de cada documento desea<\/span><\/a><span style=\"font-weight: 400\"> (dos es la opci\u00f3n m\u00e1s com\u00fan). Esta opci\u00f3n permite perder N n\u00famero de nodos sin que ello implique una posible p\u00e9rdida de datos.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-10955\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Screen-Shot-2021-03-09-at-3.06.58-PM.png\" alt=\"Atomicity-new SQL\" width=\"620\" height=\"210\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-09-at-3.06.58-PM.png 871w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-09-at-3.06.58-PM-300x102.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-09-at-3.06.58-PM-768x260.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-09-at-3.06.58-PM-20x7.png 20w\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" \/><\/p>\n<p><span style=\"font-weight: 400\">Couchbase est\u00e1 configurado por defecto para tomar siempre la aproximaci\u00f3n m\u00e1s r\u00e1pida, as\u00ed que tan pronto como tus datos lleguen al servidor, un acuse de recibo ser\u00e1 enviado de vuelta al cliente diciendo que tu escritura fue exitosa y toda la replicaci\u00f3n de datos ser\u00e1 manejada bajo el cap\u00f3. Sin embargo, si tu servidor falla antes de que tenga la oportunidad de replicar los datos (estamos hablando de microsegundos a unos pocos milisegundos, ya que la replicaci\u00f3n se realiza memoria a memoria), es posible que pierdas tu cambio. Esto puede estar bien para algunos datos de poco valor, pero... \u00a1eh! Esto viola totalmente la \"durabilidad\" en ACID. Por eso le permitimos especificar su <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/data\/durability.html#understanding-durability\"><span style=\"font-weight: 400\">requisitos de durabilidad<\/span><\/a><span style=\"font-weight: 400\">:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-10967\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Screen-Shot-2021-03-09-at-3.36.43-PM-1024x77.png\" alt=\"durabilty options\" width=\"900\" height=\"68\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-09-at-3.36.43-PM-1024x77.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-09-at-3.36.43-PM-300x23.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-09-at-3.36.43-PM-768x58.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-09-at-3.36.43-PM-20x2.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-09-at-3.36.43-PM.png 1313w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/p>\n<p><span style=\"font-weight: 400\">En <\/span><b>MAYOR\u00cdA<\/b><span style=\"font-weight: 400\"> (opci\u00f3n por defecto en la biblioteca de transacciones) en el c\u00f3digo anterior significa que la mutaci\u00f3n debe replicarse a (es decir, mantenerse en la memoria asignada al bucket en) una mayor\u00eda de los nodos del Servicio de Datos. Las otras opciones son: <\/span><b><i>majorityAndPersistActive,<\/i><\/b><span style=\"font-weight: 400\"> y <\/span><b><i>persistToMajority<\/i><\/b><span style=\"font-weight: 400\">. Consulte <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/data\/durability.html#durability-requirements\"><span style=\"font-weight: 400\">a la documentaci\u00f3n oficial sobre requisitos de durabilidad<\/span><\/a><span style=\"font-weight: 400\"> para entender mejor c\u00f3mo funciona. Esta funci\u00f3n tambi\u00e9n puede utilizarse fuera de una transacci\u00f3n en caso de que necesite garantizar de forma pesimista que un documento se ha guardado.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h3><span style=\"font-weight: 400\">\u00bfQu\u00e9 ocurre si algo falla durante una transacci\u00f3n?<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Puede configurar el tiempo que debe durar la transacci\u00f3n antes de ser revertida. El valor por defecto es de 15 segundos. Dentro de este plazo, si hay problemas de concurrencia o de nodo, utilizaremos una combinaci\u00f3n de espera y reintento hasta que la transacci\u00f3n alcance este tiempo.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Si el cliente que gestiona la transacci\u00f3n se desconecta repentinamente, es posible que deje alg\u00fan contenido escenificado en los metadatos del documento. Sin embargo, otros clientes que intenten modificar el mismo documento pueden reconocer que el contenido escenificado puede sobrescribirse, ya que forma parte de una transacci\u00f3n que ya ha caducado.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Adem\u00e1s, la biblioteca de transacciones realizar\u00e1 peri\u00f3dicamente limpiezas para eliminar las transacciones no activas de las ATR para mantenerla lo m\u00e1s peque\u00f1a posible.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-weight: 400\">Transacciones SQL distribuidas con N1QL<\/span><\/h2>\n<blockquote><p><span style=\"font-weight: 400\">N1QL <\/span><span style=\"font-weight: 400\">es un lenguaje de consulta que implementa la especificaci\u00f3n SQL++, es compatible con SQL92 pero est\u00e1 dise\u00f1ado para documentos JSON estructurados y flexibles. M\u00e1s informaci\u00f3n <\/span><a href=\"https:\/\/query-tutorial.couchbase.com\/tutorial\/#1\"><span style=\"font-weight: 400\">en este tutorial interactivo de N1QL<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/p><\/blockquote>\n<p><span style=\"font-weight: 400\">La soluci\u00f3n de transacciones distribuidas que hemos discutido hasta ahora es genial para las transacciones a nivel de aplicaci\u00f3n. Pero, a veces necesitamos ejecutar cambios de datos ad hoc. O, debido al n\u00famero de documentos involucrados en la operaci\u00f3n, manipularlos en la memoria de la aplicaci\u00f3n se convierte en una operaci\u00f3n cara (por ejemplo, a\u00f1adir 10 cr\u00e9ditos a las cuentas de todos los usuarios). En Couchbase Server 7.0, puedes ejecutar transacciones a trav\u00e9s de N1QL con pr\u00e1cticamente la misma sintaxis SQL que la mayor\u00eda de bases de datos relacionales:<\/span><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/es\/transactions-n1ql-couchbase-distributed-nosql\/\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-10968\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Screen-Shot-2021-03-12-at-2.18.31-PM-1024x834.png\" alt=\"NoSQL Transactions Vs Relational Transactions\" width=\"900\" height=\"733\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-12-at-2.18.31-PM-1024x834.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-12-at-2.18.31-PM-300x244.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-12-at-2.18.31-PM-768x625.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-12-at-2.18.31-PM-20x16.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/Screen-Shot-2021-03-12-at-2.18.31-PM.png 1028w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400\">Las transacciones N1QL ya se han introducido correctamente en <\/span><a href=\"https:\/\/www.couchbase.com\/blog\/es\/couchbase-transactions-with-n1ql\/\"><span style=\"font-weight: 400\">Transacciones Couchbase con N1QL<\/span><\/a><span style=\"font-weight: 400\"> y <\/span><a href=\"https:\/\/www.couchbase.com\/blog\/es\/use-cases-and-best-practices-to-use-distributed-transactions-in-n1ql\/\"><span style=\"font-weight: 400\">\"Casos de uso y mejores pr\u00e1cticas para transacciones distribuidas a trav\u00e9s de N1QL\"<\/span><\/a><span style=\"font-weight: 400\">por lo que no profundizar\u00e9 en este tema. Desde una vista de mil pies, la transacci\u00f3n es gestionada por el <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/services-and-indexes\/services\/query-service.html\"><span style=\"font-weight: 400\">servicio de consulta<\/span><\/a><span style=\"font-weight: 400\">. Como Couchbase es modular, puedes aumentar el rendimiento de las transacciones ampliando o reduciendo los nodos que ejecutan el servicio de consultas.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Puede utilizar las transacciones N1QL y Lambda a la vez, pero es preferible utilizar s\u00f3lo la biblioteca de transacciones siempre que sea posible.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-weight: 400\">Conclusi\u00f3n: El mejor NoSQL para transacciones<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Couchbase ya tiene soporte para operaciones at\u00f3micas de documento \u00fanico y <\/span><a href=\"https:\/\/docs.couchbase.com\/java-sdk\/current\/howtos\/concurrent-document-mutations.html\"><span style=\"font-weight: 400\">Bloqueo optimista y pesimista<\/span><\/a><span style=\"font-weight: 400\"> desde hace mucho tiempo. El a\u00f1o pasado, introdujimos soporte transaccional r\u00e1pido independientemente de buckets, colecciones, \u00e1mbitos o shards. Con Couchbase 7.0 puedes incluso usar la misma sintaxis transaccional relacional tradicional. La combinaci\u00f3n de todas estas caracter\u00edsticas hace que <strong>Couchbase, el mejor NoSQL para transacciones a escala<\/strong>.<\/span><\/p>\n<h4><span style=\"font-weight: 400\">Bajo coste - Pague por lo que use<\/span><\/h4>\n<p><span style=\"font-weight: 400\">La sobrecarga transaccional total es simplemente el n\u00famero de mutaciones de documentos + 3 (ATR marcados como Pendiente, Comprometido y Completado). Por ejemplo, ejecutar el ejemplo de transferencia de dinero en un contexto transaccional le costar\u00e1 hasta 5 llamadas adicionales a la base de datos.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">La biblioteca de transacciones es una capa sobre el SDK, hemos a\u00f1adido soporte para transacciones con cero impacto en el rendimiento (algo que otros jugadores no pueden reclamar f\u00e1cilmente). Esto solo se pudo conseguir gracias a nuestra s\u00f3lida arquitectura.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"font-weight: 400\">No hay gestor central de transacciones ni coordinador central\u00a0<\/span><\/h4>\n<p><span style=\"font-weight: 400\">Dada la arquitectura masterless de Couchbase y el hecho de que los clientes se encargan de gestionar sus propias transacciones, nuestra implementaci\u00f3n no tiene coordinaci\u00f3n central ni punto \u00fanico de fallo.\u00a0<\/span><span style=\"font-weight: 400\">Incluso durante un fallo de nodo, las transacciones que no est\u00e1n tocando documentos en el servidor defectuoso pueden completarse con \u00e9xito. De hecho, con un tiempo m\u00e1ximo de transacci\u00f3n adecuado, incluso si se tocan documentos en un nodo que est\u00e1 fallando, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/clusters-and-availability\/failover.html\"><span style=\"font-weight: 400\">Node Failover de Couchbase <\/span><\/a><span style=\"font-weight: 400\">\u00a0puede ser lo suficientemente r\u00e1pido como para aislar el servidor defectuoso y promover un nuevo nodo antes de que expire su transacci\u00f3n.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"font-weight: 400\">Sin reloj global interno y sin MVCC<\/span><\/h4>\n<p><span style=\"font-weight: 400\">Algunas implementaciones de transacciones requieren el concepto de reloj global, que puede ser caro de mantener sin hardware dedicado en un entorno distribuido. En algunos casos, puede incluso hacer caer la base de datos si la desviaci\u00f3n del reloj es superior a ~250 milisegundos.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">Con el control de concurrencia multiversi\u00f3n (MVCC) y los relojes globales, t\u00e9cnicamente se pueden alcanzar mayores niveles de coherencia. Por otro lado, lo m\u00e1s probable es que afecte al rendimiento general de la base de datos. Couchbase soporta el modelo de consistencia Read Committed, que es el mismo que las bases de datos relacionales soportan por defecto.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"font-weight: 400\">Flexibilidad<\/span><\/h4>\n<p><span style=\"font-weight: 400\">Puede utilizar la funci\u00f3n <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/data\/durability.html\"><span style=\"font-weight: 400\">opciones de durabilidad<\/span><\/a><span style=\"font-weight: 400\"> dentro y fuera de un contexto transaccional, utilice <\/span><a href=\"https:\/\/docs.couchbase.com\/java-sdk\/current\/howtos\/concurrent-document-mutations.html\"><span style=\"font-weight: 400\">bloqueo optimista y pesimista<\/span><\/a><span style=\"font-weight: 400\"> para evitar posibles problemas de concurrencia, y utilizar transacciones en el SDK y\/o a trav\u00e9s de N1QL. Hay mucha flexibilidad para construir cualquier tipo de aplicaci\u00f3n sobre Couchbase y ajustar el rendimiento a las necesidades de tu negocio.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-weight: 400\">\u00bfY ahora qu\u00e9?<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Aqu\u00ed tienes algunos enlaces para saber m\u00e1s sobre lo que acabamos de hablar y para empezar a trabajar con Couchbase:<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><span style=\"font-weight: 400\">M\u00e1s informaci\u00f3n sobre las transacciones<\/span><\/td>\n<td><a href=\"https:\/\/www.couchbase.com\/blog\/es\/transactions\/\"><span style=\"font-weight: 400\">https:\/\/www.couchbase.com\/transactions<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">Transacciones del SDK de Java<\/span><\/td>\n<td><a href=\"https:\/\/docs.couchbase.com\/java-sdk\/current\/howtos\/distributed-acid-transactions-from-the-sdk.html\"><span style=\"font-weight: 400\">https:\/\/docs.couchbase.com\/java-sdk\/current\/howtos\/distributed-acid-transactions-from-the-sdk.html<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">Transacciones del SDK de .NET<\/span><\/td>\n<td><a href=\"https:\/\/docs.couchbase.com\/dotnet-sdk\/current\/howtos\/distributed-acid-transactions-from-the-sdk.html\"><span style=\"font-weight: 400\">https:\/\/docs.couchbase.com\/dotnet-sdk\/current\/howtos\/distributed-acid-transactions-from-the-sdk.html<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">Transacciones del SDK de C<\/span><\/td>\n<td><a href=\"https:\/\/docs.couchbase.com\/cxx-txns\/current\/distributed-acid-transactions-from-the-sdk.html\"><span style=\"font-weight: 400\">https:\/\/docs.couchbase.com\/cxx-txns\/current\/distributed-acid-transactions-from-the-sdk.html<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">Transacciones N1QL<\/span><\/td>\n<td><a href=\"https:\/\/www.couchbase.com\/blog\/es\/couchbase-transactions-with-n1ql\/\"><span style=\"font-weight: 400\">https:\/\/www.couchbase.com\/blog\/couchbase-transactions-with-n1ql\/<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">Descargar Couchbase<\/span><\/td>\n<td><a href=\"https:\/\/www.couchbase.com\/blog\/es\/downloads\/\"><span style=\"font-weight: 400\">https:\/\/www.couchbase.com\/downloads<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">Novedades de Couchbase 7.0<\/span><\/td>\n<td><a href=\"https:\/\/docs.couchbase.com\/server\/7.0\/introduction\/whats-new.html\"><span style=\"font-weight: 400\">https:\/\/docs.couchbase.com\/server\/7.0\/introduction\/whats-new.html<\/span><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>ACID Transactions are a must when you have strict data consistency requirements in your application. The costs of running transactions on distributed systems can rapidly create bottlenecks at scale. In this article, we will give you an overview of some [&hellip;]<\/p>","protected":false},"author":8754,"featured_media":10999,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1814,1821,2396],"tags":[],"ppma_author":[9059],"class_list":["post-10953","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-couchbase-architecture","category-transactions"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Distributed Multi-Document ACID Transactions | Couchbase<\/title>\n<meta name=\"description\" content=\"When you have strict data consistency requirements in your application there will be challenges faced by NoSQL and NewSQL databases with ACID Transactions.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/es\/distributed-multi-document-acid-transactions\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How we implemented Distributed Multi-document ACID Transactions in Couchbase\" \/>\n<meta property=\"og:description\" content=\"When you have strict data consistency requirements in your application there will be challenges faced by NoSQL and NewSQL databases with ACID Transactions.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/distributed-multi-document-acid-transactions\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-23T08:24:55+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-27T03:17:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/IntroductionToOttoman.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Denis Rosa, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@deniswsrosa\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Denis Rosa, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/\"},\"author\":{\"name\":\"Denis Rosa, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/fe3c5273e805e72a5294611a48f62257\"},\"headline\":\"How we implemented Distributed Multi-document ACID Transactions in Couchbase\",\"datePublished\":\"2021-03-23T08:24:55+00:00\",\"dateModified\":\"2024-01-27T03:17:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/\"},\"wordCount\":4187,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/IntroductionToOttoman.jpg\",\"articleSection\":[\"Application Design\",\"Couchbase Architecture\",\"Transactions\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/\",\"name\":\"Distributed Multi-Document ACID Transactions | Couchbase\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/IntroductionToOttoman.jpg\",\"datePublished\":\"2021-03-23T08:24:55+00:00\",\"dateModified\":\"2024-01-27T03:17:43+00:00\",\"description\":\"When you have strict data consistency requirements in your application there will be challenges faced by NoSQL and NewSQL databases with ACID Transactions.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/IntroductionToOttoman.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/IntroductionToOttoman.jpg\",\"width\":1200,\"height\":628,\"caption\":\"GCP support for Couchbase Capella\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How we implemented Distributed Multi-document ACID Transactions in Couchbase\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/fe3c5273e805e72a5294611a48f62257\",\"name\":\"Denis Rosa, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/be0716f6199cfb09417c92cf7a8fa8d6\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f8d1f5c13115122cab89d0f229b904480bfe20d3dfbb093fe9734cda5235d419?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f8d1f5c13115122cab89d0f229b904480bfe20d3dfbb093fe9734cda5235d419?s=96&d=mm&r=g\",\"caption\":\"Denis Rosa, Developer Advocate, Couchbase\"},\"description\":\"Denis Rosa is a Developer Advocate for Couchbase and lives in Munich - Germany. He has a solid experience as a software engineer and speaks fluently Java, Python, Scala and Javascript. Denis likes to write about search, Big Data, AI, Microservices and everything else that would help developers to make a beautiful, faster, stable and scalable app.\",\"sameAs\":[\"https:\/\/x.com\/deniswsrosa\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/denis-rosa\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Distributed Multi-Document ACID Transactions | Couchbase","description":"When you have strict data consistency requirements in your application there will be challenges faced by NoSQL and NewSQL databases with ACID Transactions.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/es\/distributed-multi-document-acid-transactions\/","og_locale":"es_MX","og_type":"article","og_title":"How we implemented Distributed Multi-document ACID Transactions in Couchbase","og_description":"When you have strict data consistency requirements in your application there will be challenges faced by NoSQL and NewSQL databases with ACID Transactions.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/distributed-multi-document-acid-transactions\/","og_site_name":"The Couchbase Blog","article_published_time":"2021-03-23T08:24:55+00:00","article_modified_time":"2024-01-27T03:17:43+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/IntroductionToOttoman.jpg","type":"image\/jpeg"}],"author":"Denis Rosa, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@deniswsrosa","twitter_misc":{"Written by":"Denis Rosa, Developer Advocate, Couchbase","Est. reading time":"21 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/"},"author":{"name":"Denis Rosa, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/fe3c5273e805e72a5294611a48f62257"},"headline":"How we implemented Distributed Multi-document ACID Transactions in Couchbase","datePublished":"2021-03-23T08:24:55+00:00","dateModified":"2024-01-27T03:17:43+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/"},"wordCount":4187,"commentCount":1,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/IntroductionToOttoman.jpg","articleSection":["Application Design","Couchbase Architecture","Transactions"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/","url":"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/","name":"Distributed Multi-Document ACID Transactions | Couchbase","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/IntroductionToOttoman.jpg","datePublished":"2021-03-23T08:24:55+00:00","dateModified":"2024-01-27T03:17:43+00:00","description":"When you have strict data consistency requirements in your application there will be challenges faced by NoSQL and NewSQL databases with ACID Transactions.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/IntroductionToOttoman.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/IntroductionToOttoman.jpg","width":1200,"height":628,"caption":"GCP support for Couchbase Capella"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/distributed-multi-document-acid-transactions\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How we implemented Distributed Multi-document ACID Transactions in Couchbase"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"El blog de Couchbase","description":"Couchbase, la base de datos NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/fe3c5273e805e72a5294611a48f62257","name":"Denis Rosa, Defensor del Desarrollador, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/be0716f6199cfb09417c92cf7a8fa8d6","url":"https:\/\/secure.gravatar.com\/avatar\/f8d1f5c13115122cab89d0f229b904480bfe20d3dfbb093fe9734cda5235d419?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f8d1f5c13115122cab89d0f229b904480bfe20d3dfbb093fe9734cda5235d419?s=96&d=mm&r=g","caption":"Denis Rosa, Developer Advocate, Couchbase"},"description":"Denis Rosa es un Developer Advocate para Couchbase y vive en Munich - Alemania. Tiene una s\u00f3lida experiencia como ingeniero de software y habla con fluidez Java, Python, Scala y Javascript. A Denis le gusta escribir sobre b\u00fasqueda, Big Data, AI, Microservicios y todo lo que pueda ayudar a los desarrolladores a hacer una aplicaci\u00f3n hermosa, m\u00e1s r\u00e1pida, estable y escalable.","sameAs":["https:\/\/x.com\/deniswsrosa"],"url":"https:\/\/www.couchbase.com\/blog\/es\/author\/denis-rosa\/"}]}},"authors":[{"term_id":9059,"user_id":8754,"is_guest":0,"slug":"denis-rosa","display_name":"Denis Rosa, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/f8d1f5c13115122cab89d0f229b904480bfe20d3dfbb093fe9734cda5235d419?s=96&d=mm&r=g","first_name":"Denis","last_name":"Rosa, Developer Advocate, Couchbase","user_url":"","author_category":"","description":"Denis Rosa es un Developer Advocate para Couchbase y vive en Munich - Alemania. Tiene una s\u00f3lida experiencia como ingeniero de software y habla con fluidez Java, Python, Scala y Javascript. A Denis le gusta escribir sobre b\u00fasqueda, Big Data, AI, Microservicios y todo lo que pueda ayudar a los desarrolladores a hacer una aplicaci\u00f3n hermosa, m\u00e1s r\u00e1pida, estable y escalable."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/10953","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/8754"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=10953"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/10953\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/10999"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=10953"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=10953"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=10953"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=10953"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}