

 Amazon Redshift dejará de admitir la creación de nuevas UDF de Python a partir del parche 198. Las UDF de Python existentes seguirán funcionando hasta el 30 de junio de 2026. Para obtener más información, consulte la [publicación del blog](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

# Administración de operaciones de escritura simultáneas
<a name="c_Concurrent_writes"></a>

Algunas aplicaciones no solo requieren la ejecución simultánea de consultas y cargas, sino también la capacidad de escribir en distintas tablas o en la misma tabla de manera simultánea. En este contexto, *simultánea* significa "superpuesta", no "programada para que se ejecute exactamente al mismo tiempo". Dos transacciones se consideran simultáneas si la segunda comienza antes de que se confirme la primera. Las operaciones concurrentes pueden originarse en sesiones diferentes controladas por el mismo usuario o por usuarios diferentes. 

Amazon Redshift es compatible con estos tipos de aplicaciones porque permite que las tablas se lean mientras se cargan o modifican de forma progresiva. Las consultas simplemente ven la última versión confirmada o una *instantánea* de los datos, en lugar de esperar a que se confirme la siguiente versión. Si desea que una consulta particular espere por una confirmación de otra operación de escritura, debe programarla de manera acorde.

**nota**  
Amazon Redshift admite el comportamiento de *confirmación automática* predeterminado en el que cada comando SQL ejecutado por separado se confirma individualmente. Si incluye un conjunto de comandos en un bloque de transacciones (definido por instrucciones [BEGIN](r_BEGIN.md) y [END](r_END.md)), el bloque se confirma como una transacción, de manera que puede revertirse de ser necesario. Las excepciones a este comportamiento son los comandos TRUNCATE y VACUUM, que confirman automáticamente todos los cambios pendientes realizados en la transacción actual.   
Algunos clientes SQL emiten los comandos BEGIN y COMMIT automáticamente, por lo que el cliente controla si un grupo de instrucciones se ejecuta como una transacción o si cada instrucción individual se ejecuta como su propia transacción. Consulte la documentación de la interfaz que está utilizando. Por ejemplo, cuando se utiliza el controlador JDBC de Amazon Redshift, una cadena `PreparedStatement` de JDBC con consulta que contiene varios comandos SQL (separados por punto y coma) ejecuta todas las instrucciones como una sola transacción. Por el contrario, si utiliza SQL Workbench/J y establece AUTO COMMIT ON, si ejecuta varias instrucciones, cada una de ellas se ejecuta como una transacción propia. 

En los temas a continuación, se describen algunos de los conceptos clave y los casos de uso que incluyen transacciones, instantáneas de base de datos, actualizaciones y comportamiento simultáneo.

**Topics**
+ [Niveles de aislamiento en Amazon Redshift](c_serial_isolation.md)
+ [Operaciones de lectura y escritura y de escritura](c_write_readwrite.md)
+ [Ejemplos de escritura simultánea](r_Serializable_isolation_example.md)
+ [Solución de problemas de errores de aislamiento serializable](c_serial_isolation-serializable-isolation-troubleshooting.md)

# Niveles de aislamiento en Amazon Redshift
<a name="c_serial_isolation"></a>

Las operaciones de escritura simultáneas son compatibles con Amazon Redshift en modo protegido, con bloqueos de escritura en las tablas y el principio de *aislamiento serializable*. El aislamiento serializable conserva la ilusión de que una transacción que se ejecuta en una tabla es la única transacción ejecutándose en ella.

Las bases de datos de Amazon Redshift admiten operaciones de escritura simultáneas, ya que cada operación utiliza la última versión confirmada, o instantánea, de sus datos al inicio de la transacción. Una instantánea de base de datos se crea dentro de una transacción con la primera aparición de la mayoría de las instrucciones SELECT, los comandos DML como COPY, DELETE, INSERT, UPDATE y TRUNCATE, y los siguientes comandos DDL:
+  ALTER TABLE (para agregar o eliminar columnas) 
+  CREATE TABLE 
+  DROP TABLE 
+  TRUNCATE TABLE 

Ninguna otra transacción puede cambiar esta instantánea, lo que significa que las transacciones están aisladas unas de otras. Es decir, las transacciones simultáneas son invisibles entre sí, no pueden detectar los cambios de la otra.

Cualquier ejecución simultánea de transacciones debe producir los mismos resultados que la ejecución en serie de esas transacciones. Si ninguna ejecución en serie de esas transacciones puede producir los mismos resultados, la transacción que ejecuta una instrucción que podría afectar la capacidad de serialización se anula y revierte.

Por ejemplo, supongamos que un usuario intenta ejecutar dos transacciones simultáneas, T1 y T2. La ejecución de T1 y T2 debe producir los mismos resultados que al menos uno de los siguientes escenarios:
+ T1 y T2 se ejecutan en serie en ese orden.
+ T2 y T1 se ejecutan en serie en ese orden.

 Los niveles de aislamiento de Amazon Redshift evitan los siguientes problemas: 
+  Lecturas incorrectas: una lectura incorrecta se produce cuando una transacción lee datos que aún no se han confirmado. Por ejemplo, supongamos que la transacción 1 actualiza una fila. La transacción 2 lee la fila actualizada antes de que T1 confirme la actualización. Si T1 anula el cambio, T2 habrá leído los datos de las filas no confirmadas que Amazon Redshift considera ahora que nunca existieron. 
+  Lecturas no repetibles: se produce una lectura no repetible cuando una sola transacción lee la misma fila dos veces, pero obtiene datos diferentes cada vez. Por ejemplo, supongamos que la transacción 1 lee una fila. La transacción 2 actualiza o elimina esa fila y confirma la actualización o la eliminación. Si T1 vuelve a leer la fila, recupera valores de fila diferentes o descubre que la fila se ha eliminado. 
+  Fantasmas: un fantasma es una fila que coincide con los criterios de búsqueda pero que no se ve inicialmente. Por ejemplo, supongamos que la transacción 1 lee un conjunto de filas que cumplen sus criterios de búsqueda. La transacción 2 genera una nueva fila en una instrucción UPDATE o INSERT que coincide con los criterios de búsqueda de T1. Si T1 vuelve a ejecutar su instrucción de búsqueda, obtiene un conjunto de filas diferente. 

## Aislamiento SNAPSHOT y SERIALIZABLE
<a name="c_serial_isolation-snapshot_and_serializable"></a>

Los aislamientos SNAPSHOT y SERIALIZABLE son dos niveles de aislamiento serializable disponibles en Amazon Redshift. 

El aislamiento SNAPSHOT es el nivel de aislamiento predeterminado al crear clústeres aprovisionados y grupos de trabajo sin servidor, lo que permite procesar volúmenes de datos más grandes que el aislamiento SERIALIZABLE en menos tiempo.

El aislamiento SERIALIZABLE lleva más tiempo, pero implementa restricciones más estrictas en las transacciones simultáneas. Este nivel de aislamiento evita problemas como las anomalías en el sesgo de escritura, ya que solo permite que se confirme una transacción y cancela todas las demás transacciones simultáneas con un error de infracción del aislamiento que se puede serializar.

A continuación, se muestra un ejemplo cronológico de cómo se gestionarían dos operaciones de escritura simultáneas al utilizar el aislamiento SNAPSHOT. La instrucción UPDATE de cada usuario puede confirmarse porque no entra en conflicto al intentar actualizar las mismas filas.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/redshift/latest/dg/c_serial_isolation.html)

Si se ejecuta el mismo escenario mediante aislamiento serializable, Amazon Redshift termina el usuario 2 debido a una infracción serializable y devuelve un error `1023`. Para obtener más información, consulte [Solución de problemas de errores de aislamiento serializable](c_serial_isolation-serializable-isolation-troubleshooting.md). En este caso, solo el usuario 1 puede confirmar correctamente. 

## Consideraciones
<a name="c_serial_isolation-considerations"></a>

Cuando utilice niveles de aislamiento en Amazon Redshift, tenga en cuenta lo siguiente:
+  Consulte la vista del catálogo STV\$1DB\$1ISOLATION\$1LEVEL para ver qué nivel de aislamiento utiliza la base de datos. Para obtener más información, consulte [STV\$1DB\$1ISOLATION\$1LEVEL](r_STV_DB_ISOLATION_LEVEL.md). 
+  Consulte la vista de PG\$1DATABASE\$1INFO para ver cuántas transacciones simultáneas se admiten para la base de datos. Para obtener más información, consulte [PG\$1DATABASE\$1INFO](r_PG_DATABASE_INFO.md). 
+  Las tablas de catálogo del sistema (PG) y otras tablas del sistema de Amazon Redshift no se bloquean en una transacción. Por lo tanto, los cambios realizados en los objetos de base de datos que surjan de las operaciones DDL y TRUNCATE son visibles con cualquier transacción simultánea cuando se confirman. 

   Por ejemplo, supongamos que la tabla A existe en la base de datos al momento en que comienzan dos transacciones simultáneas, T1 y T2. Supongamos que T2 devuelve una lista de tablas al seleccionar las de la tabla de catálogo PG\$1TABLES. Luego T1 elimina la tabla A y confirma los cambios y, a continuación, T2 vuelve a especificar las tablas. La tabla A ya no aparece en la lista. Si T2 intenta ejecutar una consulta en la tabla eliminada, Amazon Redshift devuelve un error de tipo “la relación no existe”. La consulta de catálogo que le devuelve la lista de tablas a T2 o que verifica la existencia de la tabla A no se encuentra sujeta a las mismas reglas de aislamiento que las operaciones que se realizan en las tablas de usuario. 

   Las transacciones de las actualizaciones de estas tablas se ejecutan en un modo de aislamiento de lectura confirmada. 
+  Las tablas de catálogo con el prefijo PG no son compatibles con el aislamiento de SNAPSHOT. 

# Operaciones de lectura y escritura y de escritura
<a name="c_write_readwrite"></a>

Puede administrar el comportamiento específico de las operaciones simultáneas de escritura al decidir cuándo y cómo ejecutar diferentes tipos de comandos. Los siguientes comandos son relevantes en este análisis: 
+ Comandos COPY, que realizan cargas (iniciales o incrementales).
+ Comandos INSERT, que agregan una o más filas por vez.
+ Comandos UPDATE, que modifican filas existentes.
+ Comandos DELETE, que eliminan filas. 

Las operaciones COPY e INSERT son operaciones de escritura pura. Las operaciones DELETE y UPDATE son operaciones de lectura/escritura (para eliminar o actualizar filas, primero hay que leerlas). Los resultados de las operaciones simultáneas de escritura dependen de los comandos específicos que se están ejecutando simultáneamente. 

Las operaciones UPDATE y DELETE se comportan de manera diferente porque dependen de una lectura inicial de la tabla antes de cualquier escritura. Dado que las transacciones simultáneas son invisibles entre sí, tanto UPDATE como DELETE deben leer una snapshot de los datos de la última confirmación. Cuando la primera operación UPDATE o DELETE levanta el bloqueo, la segunda debe determinar si los datos con los que trabajará son potencialmente obsoletos. No lo serán, porque la segunda transacción no obtiene su snapshot de los datos sino hasta después de que la primera transacción haya levantado su bloqueo.

## Posible situación de bloqueo para transacciones de escritura simultáneas que involucran múltiples tablas
<a name="c_write_readwrite-potential-deadlock"></a>

Cuando las transacciones involucren actualizaciones de más de una tabla, existe la posibilidad de que transacciones que se ejecutan de manera simultánea se bloqueen al querer escribir en el mismo conjunto de tablas. Una transacción levanta todos los bloqueos de tabla a la vez, ya sea cuando confirma o cuando se revierte; no los libera de a uno.

Por ejemplo, supongamos que las transacciones T1 y T2 comienzan, aproximadamente, al mismo tiempo. Si T1 comienza a escribir en la tabla A y T2 comienza a escribir en la tabla B, ambas transacciones pueden continuar sin conflictos. No obstante, si T1 finaliza la escritura de la tabla A y necesita comenzar a escribir en la tabla B, no podrá hacerlo porque T2 aún la bloquea. Del mismo modo, si T2 termina de escribir en la tabla B y necesita comenzar a escribir en la tabla A, tampoco podrá hacerlo porque T1 aún la bloquea. Como ninguna de las transacciones puede liberar los bloqueos sino hasta que todas las operaciones de escritura se hayan confirmado, ninguna transacción puede avanzar. Para evitar este tipo de bloqueo, debe programar las operaciones de escritura simultáneas con sumo cuidado. Por ejemplo, siempre debe actualizar las tablas en el mismo orden en las transacciones y, si especifica bloqueos, bloquee las tablas en el mismo orden antes de realizar cualquier operación DML. 

## Posible situación de bloqueo para transacciones de escritura simultáneas que involucran una sola tabla
<a name="c_write_readwrite-potential-deadlock-single"></a>

En un entorno de aislamiento de instantáneas, pueden producirse bloqueos al ejecutar transacciones de escritura simultáneas en la misma tabla. El bloqueo de aislamiento de instantáneas ocurre cuando las instrucciones INSERT o COPY simultáneas comparten un bloqueo y avanzan, y otra instrucción necesita realizar una operación (UPDATE, DELETE, MERGE o DDL) que requiere un bloqueo exclusivo en la misma tabla. 

Veamos la siguiente situación:

Transacción 1 (T1):

```
INSERT/COPY INTO table_A;
```

Transacción 2 (T2):

```
INSERT/COPY INTO table_A; 
            <UPDATE/DELETE/MERGE/DDL statement> table_A
```

Puede producirse un bloqueo cuando varias transacciones con operaciones INSERT o COPY se ejecutan simultáneamente en la misma tabla con un bloqueo compartido, y una de esas transacciones sigue la operación de escritura pura con una operación que requiere un bloqueo exclusivo, como una instrucción UPDATE, MERGE, DELETE o DDL.

Para evitar el bloqueo en estas situaciones, puede separar las instrucciones que requieren un bloqueo exclusivo (instrucciones UPDATE/MERGE/DELETE/DDL) en una transacción diferente para que las instrucciones INSERT/COPY puedan progresar simultáneamente y las instrucciones que requieren bloqueos exclusivos puedan ejecutarse después de ellas. De forma alternativa, para transacciones con instrucciones INSERT/COPY y MERGE/UPDATE/MERGE en la misma tabla, puede incluir lógica de reintento en las aplicaciones para evitar posibles bloqueos. 

# Ejemplos de escritura simultánea
<a name="r_Serializable_isolation_example"></a>

En los siguientes ejemplos de pseudocódigo, se demuestra cómo, cuando se ejecutan de manera simultánea, las transacciones avanzan o esperan.

## Ejemplos de escritura simultánea con aislamiento serializable
<a name="r_Serializable_isolation_example-serializable"></a>

### Operaciones COPY simultáneas en la misma tabla con aislamiento serializable
<a name="r_Serializable_isolation_example-concurrent-copy-operations-into-the-same-table"></a>

La transacción 1 copia filas en la tabla LISTING: 

```
begin;
copy listing from ...;
end;
```

La transacción 2 comienza de manera simultánea en una sesión por separado y copia más filas en la tabla LISTING. La transacción 2 debe esperar hasta que la transacción 1 levante el bloqueo de escritura de la tabla LISTING; luego, podrá avanzar. 

```
begin;
[waits]
copy listing from ;
end;
```

El mismo comportamiento se observaría si una o ambas transacciones tuvieran un comando INSERT, en lugar de COPY.

### Operaciones DELETE simultáneas desde la misma tabla con aislamiento serializable
<a name="r_Serializable_isolation_example-concurrent-delete-operations-from-the-same-table"></a>

La transacción 1 elimina filas de una tabla: 

```
begin;
delete from listing where ...;
end;
```

La transacción 2 comienza de manera simultánea y elimina filas de la misma tabla. Tendrá éxito porque espera a que la transacción 1 termine antes de probar eliminar filas.

```
begin
[waits]
delete from listing where ;
end;
```

El mismo comportamiento se observaría si una o ambas transacciones tuvieran un comando UPDATE para la misma tabla, en lugar de DELETE.

### Transacciones simultáneas con una mezcla de operaciones de lectura y escritura con aislamiento serializable
<a name="r_Serializable_isolation_example-concurrent-transactions"></a>

En este ejemplo, la transacción 1 elimina filas de la tabla USERS, vuelve a cargar la tabla, ejecuta una consulta COUNT(\$1) y, luego, ANALYZE, antes de confirmar: 

```
begin;
delete one row from USERS table;
copy ;
select count(*) from users;
analyze ;
end;
```

Mientras tanto, comienza la transacción 2. Esta transacción prueba copiar filas adicionales en la tabla USERS, analizarla y, luego, ejecutar la misma consulta COUNT(\$1) que la primera transacción:

```
begin;
[waits]
copy users from ...;
select count(*) from users;
analyze;
end;
```

La segunda transacción tendrá éxito porque debe esperar a que la primera termine. Su consulta COUNT devolverá el recuento en función de la carga que ha completado.

## Ejemplos de escritura simultánea con aislamiento de instantánea
<a name="r_Serializable_isolation_example-snapshot"></a>

### Operaciones de copia simultáneas en la misma tabla con aislamiento de instantánea
<a name="r_Serializable_isolation_example-concurrent-copy-operations-into-the-same-table-snapshot"></a>

La transacción 1 copia filas en la tabla LISTING:

```
begin;
copy listing from ...;
end;
```

La transacción 2 comienza de manera simultánea en una sesión por separado y copia más filas en la tabla LISTING. La transacción 2 puede progresar simultáneamente hasta que cualquiera de las transacciones necesite escribir datos en la tabla de destino `listing`, momento en el que se ejecutarán secuencialmente. 

```
begin; 
//When the COPY statement from T1 needs to write data to the table, the COPY statement from T2 waits.
copy listing from ...; 
end;
```

El mismo comportamiento se observaría si una o ambas transacciones tuvieran un comando INSERT, en lugar de COPY.

### Operaciones DELETE simultáneas desde la misma tabla con aislamiento de instantánea
<a name="r_Serializable_isolation_example-concurrent-delete-operations-from-the-same-table-snapshot"></a>

Las operaciones DELETE y UPDATE simultáneas desde la misma tabla con aislamiento de instantánea se ejecutan igual que las operaciones ejecutadas con aislamiento serializable.

### Transacciones simultáneas con una mezcla de operaciones de lectura y escritura con aislamiento de instantánea
<a name="r_Serializable_isolation_example-concurrent-transactions-snapshot"></a>

Las transacciones simultáneas que se ejecutan con mezclas de operaciones con aislamiento de instantánea se ejecutan igual que las transacciones con mezclas de operaciones que se ejecutan con aislamiento serializable.

# Solución de problemas de errores de aislamiento serializable
<a name="c_serial_isolation-serializable-isolation-troubleshooting"></a>

## ERROR:1023 DETAIL: Serializable isolation violation on a table in Redshift
<a name="c_serial_isolation-serialization-isolation-1023"></a>

Cuando Amazon Redshift detecta un error de aislamiento serializable, se muestra un mensaje de error como el siguiente.

```
ERROR:1023 DETAIL: Serializable isolation violation on table in Redshift
```

Para solucionar el error de aislamiento serializable, puede probar los métodos siguientes:
+ Volver a intentar la transacción cancelada.

   Amazon Redshift detectó que una carga de trabajo simultánea no es serializable. Sugiere que hay deficiencias en la lógica de la aplicación, que por lo general se pueden solucionar si se intenta realizar la transacción en la que se encontró el error de nuevo. Si el problema persiste, pruebe uno de los métodos siguientes. 
+ Mover cualquier operación que no tenga que estar en la misma transacción atómica fuera de la transacción.

  Este método se aplica cuando las operaciones individuales dentro de dos transacciones tienen referencias cruzadas entre sí de forma que pueden afectar al resultado de la otra transacción. Por ejemplo, las dos sesiones siguientes inician una transacción cada una. 

  ```
  Session1_Redshift=# begin;
  ```

  ```
  Session2_Redshift=# begin;
  ```

  El resultado de la instrucción SELETCT en cada transacción se podría ver afectado por una instrucción INSERT en la otra. Dicho de otro modo, suponga que ejecuta las siguientes instrucciones en serie, en cualquier orden. En cada caso, el resultado es que una de las instrucciones SELECT devuelve una fila más que si las transacciones se ejecutaran de forma simultánea. No hay ningún orden en que las operaciones se puedan ejecutar en serie que produzca el mismo resultado que cuando se ejecutan de forma simultánea. Así, la última operación que se ejecuta da lugar a un error de aislamiento serializable.

  ```
  Session1_Redshift=# select * from tab1;
  Session1_Redshift=# insert into tab2 values (1);
  ```

  ```
  Session2_Redshift=# insert into tab1 values (1);
  Session2_Redshift=# select * from tab2;
  ```

  En muchos casos, el resultado de las instrucciones SELECT no es importante. Dicho de otro modo, la atomicidad de las operaciones en las transacciones no es importante. En estos casos, saque las instrucciones SELECT de sus transacciones, como se muestra en los ejemplos siguientes.

  ```
  Session1_Redshift=# begin;
  Session1_Redshift=# insert into tab1 values (1)
  Session1_Redshift=# end;
  Session1_Redshift=# select * from tab2;
  ```

  ```
  Session2_Redshift # select * from tab1;
  Session2_Redshift=# begin;
  Session2_Redshift=# insert into tab2 values (1)
  Session2_Redshift=# end;
  ```

  En estos ejemplos, no hay ninguna referencia cruzada en las transacciones. Las dos instrucciones INSERT no se ven afectadas entre sí. En estos ejemplo, hay al menos un orden en el que las transacciones se pueden ejecutar en serie y producir el mismo resultado que si se ejecutan de manera simultánea. Estos significa que las transacciones son serializables.
+ Obligue a la serialización bloqueando todas las tablas en cada sesión.

  El comando [LOCK](r_LOCK.md) bloquea operaciones que dan lugar a errores de aislamiento serializable. Cuando utilice el comando LOCK, asegúrese de hacer lo siguiente:
  + Bloquee todas las tablas que se ven afectadas por la transacción, incluidas aquellas afectadas por instrucciones SELECT de solo lectura dentro de la transacción.
  + Bloquee las tablas en el mismo orden, con independencia del orden en que se ejecutan las operaciones.
  + Bloquee todas las tablas al principio de la transacción, antes de llevar a cabo alguna operación.
+ Utilizar el aislamiento de instantáneas para transacciones simultáneas

  Utilice un comando ALTER DATABASE con aislamiento de instantáneas. Para obtener más información sobre el parámetro SNAPSHOT para ALTER DATABASE, consulte [Parameters](r_ALTER_DATABASE.md#r_ALTER_DATABASE-parameters).

## ERROR:1018 DETAIL: Relation does not exist
<a name="c_serial_isolation-serialization-isolation-1018"></a>

Cuando ejecuta operaciones simultáneas de Amazon Redshift en sesiones diferentes, se muestra un mensaje de error como el siguiente.

```
ERROR: 1018 DETAIL: Relation does not exist.
```

Las transacciones en Amazon Redshift utilizan el aislamiento de la instantánea. Una vez que se inicia una transacción, Amazon Redshift toma una instantánea de la base de datos. En todo el ciclo de vida de la transacción, la transacción realiza las operaciones en el estado de la base de datos como se refleja en la instantánea. Si la transacción realiza la lectura desde una tabla que no existe en la instantánea, arroja el mensaje de error 1018 mostrado anteriormente. Incluso cuando otra transacción simultánea crea una tabla después de que la transacción haya tomado la instantánea, la transacción no puede realizar la lectura desde la tabla recién creada.

Para solucionar este error de serialización del aislamiento, puede intentar cambiar el inicio de la transacción a un punto en el que sepa que existe la tabla.

Si otra transacción crea la tabla, este punto será después de que se haya confirmado la transacción. Además, asegúrese de que no se haya confirmado ninguna transacción simultánea que pueda haber eliminado la tabla.

```
session1 = # BEGIN;
session1 = # DROP TABLE A;
session1 = # COMMIT;
```

```
session2 = # BEGIN;
```

```
session3 = # BEGIN;
session3 = # CREATE TABLE A (id INT);
session3 = # COMMIT;
```

```
session2 = # SELECT * FROM A;
```

La última operación que ejecuta session2 como la operación de lectura da lugar a un error de aislamiento serializable. Este error ocurre cuando session2 toma una instantánea y la tabla ya ha sido eliminada por una session1 confirmada. En otras palabras, aunque una session3 simultánea haya creado la tabla, la session2 no ve la tabla porque no está en la instantánea.

Para resolver este error, puede reordenar las sesiones de la siguiente manera.

```
session1 = # BEGIN;
session1 = # DROP TABLE A;
session1 = # COMMIT;
```

```
session3 = # BEGIN;
session3 = # CREATE TABLE A (id INT);
session3 = # COMMIT;
```

```
session2 = # BEGIN;
session2 = # SELECT * FROM A;
```

Cuando session2 toma su instantánea, session3 ya se ha confirmado y la tabla está en la base de datos. La session2 puede leer desde la tabla sin ningún error.