<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Transacciones on Hernán's Blog</title><link>https://hernan941.com/tags/transacciones/</link><description>Recent content in Transacciones on Hernán's Blog</description><generator>Hugo -- gohugo.io</generator><language>es-CL</language><managingEditor>hrwgallardo@gmail.com (Hernán)</managingEditor><webMaster>hrwgallardo@gmail.com (Hernán)</webMaster><copyright>Hernán (CC BY 4.0)</copyright><lastBuildDate>Mon, 23 Feb 2026 12:51:00 -0300</lastBuildDate><atom:link href="https://hernan941.com/tags/transacciones/index.xml" rel="self" type="application/rss+xml"/><item><title>Transacciones y Concurrencia: lo que deberías saber</title><link>https://hernan941.com/posts/concurrencia/</link><pubDate>Mon, 23 Feb 2026 12:51:00 -0300</pubDate><author>hrwgallardo@gmail.com (Hernán)</author><guid>https://hernan941.com/posts/concurrencia/</guid><description>&lt;p&gt;Hay conceptos que marcan la diferencia entre un software engineer junior y uno senior. Conceptos que llenarían varios libros. Aquí intento acortar un poco esa brecha entre lo que sabemos y cómo se conecta todo.&lt;/p&gt;
&lt;p&gt;Las últimas semanas le he estado dando vueltas al funcionamiento de las operaciones y la concurrencia. ¿Qué nos garantiza que una operación crítica no rompa el sistema?&lt;/p&gt;
&lt;h2 id="fundamentos-de-transacciones"&gt;Fundamentos de Transacciones&lt;/h2&gt;
&lt;p&gt;Nada. No existe una configuración correcta para todos los casos. Lo que sí existe es entender cómo se comportan los estados de las transacciones cuando funcionan en conjunto. Una transacción es un contrato de consistencia. Cuando no entendemos qué ocurre en los niveles de abajo, dejamos la integridad del sistema a la suerte.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Hay conceptos que marcan la diferencia entre un software engineer junior y uno senior. Conceptos que llenarían varios libros. Aquí intento acortar un poco esa brecha entre lo que sabemos y cómo se conecta todo.</p>
<p>Las últimas semanas le he estado dando vueltas al funcionamiento de las operaciones y la concurrencia. ¿Qué nos garantiza que una operación crítica no rompa el sistema?</p>
<h2 id="fundamentos-de-transacciones">Fundamentos de Transacciones</h2>
<p>Nada. No existe una configuración correcta para todos los casos. Lo que sí existe es entender cómo se comportan los estados de las transacciones cuando funcionan en conjunto. Una transacción es un contrato de consistencia. Cuando no entendemos qué ocurre en los niveles de abajo, dejamos la integridad del sistema a la suerte.</p>
<p>Esto se vuelve evidente cuando nos toca trabajar en servicios financieros, criptomonedas, gestión de inventario, reservas o sistemas distribuidos.</p>
<h2 id="transacciones-acid">Transacciones ACID</h2>
<p>Cuando las bases de datos comenzaron a usarse en sistemas críticos, las fallas dejaban datos en estados inconsistentes, generando errores costosos. En los años 80, Jim Gray junto a otros investigadores definió las propiedades ACID: Atomicidad, Consistencia, Aislamiento y Durabilidad. Cuatro reglas que garantizan que, incluso ante fallos, los datos se mantengan correctos.</p>
<h4 id="atomicidad">Atomicidad</h4>
<p>Es la idea del &ldquo;todo o nada&rdquo;. Una transacción puede tener 10 pasos, pero si el paso 9 falla, los otros 8 se deshacen como si nunca hubieran existido. Esto se logra mediante Logs (Write-Ahead Logging).  La base de datos anota lo que va a hacer antes de tocar los datos reales. Si hay un error, usa ese log para aplicar un Rollback y volver al estado inicial.</p>
<h4 id="consistencia">Consistencia</h4>
<p>Garantiza que una transacción solo lleve a la base de datos de un estado valido a otro. El centro de esta propiedad es asegurar las reglas del negocio. Las herramientas que aparecen son los Triggers, Foreign Keys, Check Constraints y tipos de datos. Por ejemplo. Si intentas poner un volumen negativo y hay una regla que lo prohíbe, la transacción rebota.</p>
<h4 id="aislamiento">Aislamiento</h4>
<p>Aquí es donde la cosa se pone interesante. Cuando varias transacciones intentan acceder y modificar el mismo recurso al mismo tiempo, no pueden simplemente ejecutarse en paralelo sin coordinación. Si lo hicieran, terminaríamos con estados inconsistentes. Por eso, una transacción debe esperar su turno mientras otra termina su operación sobre ese mismo dato.</p>
<p>La concurrencia ocurre cuando la ejecución de dos o más fragmentos de código actúa como si se ejecutaran al mismo tiempo.</p>
<p>Para lidiar con la concurrencia, la coordinación se logra con primitivas de exclusión mutua. A bajo nivel hablamos de mutex: mecanismos que garantizan que solo un hilo o proceso acceda a un recurso crítico a la vez (<a href="https://www.youtube.com/watch?v=1tZhmTnk-vc">si quieres saber más</a>). En bases de datos, el concepto se traduce en locks, que aplican esa exclusión sobre filas, páginas o tablas. No es cooperación opcional; el motor impone estas reglas para proteger la integridad.</p>
<table>
	<thead>
			<tr>
					<th>Tipo de Locking</th>
					<th>Descripción</th>
					<th>Características</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Pessimistic Locking 🙁</td>
					<td>&ldquo;Pongo un candado al dato hasta que termine&rdquo;</td>
					<td>Nadie más toca nada. Es seguro pero lento.</td>
			</tr>
			<tr>
					<td>Optimistic Locking 🙂</td>
					<td>&ldquo;No pongo candado, asumo que nadie más lo tocará&rdquo;</td>
					<td>Al final, verifico si alguien cambió algo. Si alguien lo hizo, aborto y reintento. Es mucho más rápido para sistemas con mucho tráfico.</td>
			</tr>
	</tbody>
</table>
<p>Ahora bien, ¿cuándo y cómo se aplican estos locks? Ahí es donde entran los <strong>niveles de aislamiento</strong>: configuraciones que definen qué tan estricta será la base de datos al momento de aplicar locks entre transacciones concurrentes. Cada nivel hace diferentes trade-offs entre consistencia y rendimiento:</p>
<table>
	<thead>
			<tr>
					<th>Nivel</th>
					<th>Descripción</th>
					<th>Características</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Read Uncommitted</td>
					<td>El &ldquo;Salvaje Oeste&rdquo;</td>
					<td>Una transacción puede ver cambios de otra que aún no se han confirmado. Riesgo: Lecturas sucias.</td>
			</tr>
			<tr>
					<td>Read Committed</td>
					<td>Estándar en PostgreSQL</td>
					<td>Solo puedes leer datos que ya han sido confirmados (Committed).</td>
			</tr>
			<tr>
					<td>Repeatable Read</td>
					<td>Evita lectura no repetible</td>
					<td>Garantiza que si lees un registro dos veces en la misma transacción, verás lo mismo, incluso si alguien más lo modificó entre medias.</td>
			</tr>
			<tr>
					<td>Serializable</td>
					<td>Nivel máximo de seguridad</td>
					<td>Las transacciones se ejecutan como si estuvieran en una fila india, una tras otra, aunque ocurran en paralelo. Es el más seguro pero el más lento.</td>
			</tr>
	</tbody>
</table>
<h4 id="durabilidad">Durabilidad</h4>
<p>Es la promesa de que, una vez que el sistema te dice &ldquo;OK, guardado&rdquo;, esa información no se perderá ni aunque se vaya la luz o el servidor explote justo después.</p>
<p><img src="https://upload.wikimedia.org/wikipedia/en/thumb/1/11/Disaster_Girl.jpg/250px-Disaster_Girl.jpg" alt="Disaster Girl"></p>
<p>Los cambios se escriben en memoria no volátil (disco duro/SSD) y se confirman en el log de transacciones. Incluso tras un fallo catastrófico, al reiniciar, la base de datos lee el log y termina de aplicar lo que quedó pendiente.</p>
<h2 id="más-allá-de-acid">Más allá de ACID</h2>
<p>Hoy en día, estos conceptos son la fundación de las bases de datos relacionales. Sin embargo, entender esto es solo el primer paso. Cuando das el salto a arquitecturas modernas con microservicios y bases de datos NoSQL, el motor ya no puede garantizar ACID en todo el sistema, porque tus datos ahora viven en servidores separados y las reglas del juego cambian.</p>
<p>Al distribuir la información, la rigidez de ACID a menudo se cambia por un enfoque más flexible que prioriza que el sistema nunca se caiga. A este nuevo paradigma lo llamamos BASE:</p>
<table>
	<thead>
			<tr>
					<th>Propiedad BASE</th>
					<th>Descripción</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>B</strong>asically Available</td>
					<td>El sistema garantiza que siempre responderá a las peticiones, incluso si algunos nodos o servidores fallan.</td>
			</tr>
			<tr>
					<td><strong>S</strong>oft state</td>
					<td>Como los datos se están sincronizando entre servidores, el estado del sistema puede cambiar con el tiempo, incluso si no hay nuevas operaciones de escritura.</td>
			</tr>
			<tr>
					<td><strong>E</strong>ventual consistency</td>
					<td>La promesa de que, si dejamos de enviar cambios y esperamos lo suficiente, todos los servidores eventualmente tendrán la misma versión de los datos.</td>
			</tr>
	</tbody>
</table>
<p>Pasar de ACID a BASE significa aceptar que tu sistema vivirá con cierta inconsistencia temporal a cambio de ser increíblemente rápido y resistente a caídas masivas. En este punto la integridad de los datos deja de venir desde la configuración del motor y se convierte en patrones de diseño que debes implementar en el código (como el patrón Saga o el Two-Phase Commit) para atar los cabos sueltos.</p>
<p>Pero esa&hellip; es una historia para otro post.</p>
]]></content:encoded></item></channel></rss>