Simultaneidad y coherencia de los datos

El contenido del script de esta página es sólo para fines de navegación y no modifica el contenido de ninguna forma.

En este capítulo se explica cómo Oracle AI Database mantiene los datos consistentes en un entorno de base de datos de varios usuarios.

Introducción a la simultaneidad y coherencia de los datos

En una base de datos de un solo usuario, un usuario puede modificar los datos sin preocuparse de que otros usuarios modifiquen los mismos datos al mismo tiempo. Sin embargo, en una base de datos multiusuario, las sentencias de varias transacciones simultáneas pueden actualizar los mismos datos. Las transacciones que se ejecutan simultáneamente deben producir resultados significativos y coherentes.

Una base de datos de varios usuarios debe proporcionar lo siguiente:

Para describir el comportamiento consistente de las transacciones cuando se ejecutan simultáneamente, los investigadores de la base de datos han definido un modelo de aislamiento de transacciones denominado serializabilidad. Una transacción serializable funciona en un entorno que hace que parezca como si ningún otro usuario estuviera modificando datos en la base de datos.

Aunque este grado de aislamiento entre transacciones suele ser deseable, la ejecución de muchas aplicaciones en modo serializable puede comprometer gravemente el rendimiento de la aplicación. El aislamiento completo de las transacciones en ejecución simultánea podría significar que una transacción no puede realizar una inserción en una tabla que consulta otra transacción. En resumen, las consideraciones del mundo real generalmente requieren un compromiso entre el aislamiento perfecto de las transacciones y el rendimiento.

Oracle AI Database mantiene la consistencia de los datos mediante un modelo de consistencia de multiversión y varios tipos de bloqueos y transacciones. De esta forma, la base de datos puede presentar una vista de datos a varios usuarios simultáneos, con cada vista consistente hasta un punto en el tiempo. Debido a que pueden existir diferentes versiones de bloques de datos simultáneamente, las transacciones pueden leer la versión de los datos confirmados en el punto en el tiempo requerido por una consulta y devolver resultados que sean consistentes en un único punto en el tiempo.

Consistencia de Lectura de Multiversión

En Oracle AI Database, la multiversión es la capacidad de materializar simultáneamente varias versiones de datos. Oracle AI Database mantiene la consistencia de lectura de varias versiones.

Las consultas de una base de datos Oracle tienen las siguientes características:

Consistencia de Lectura a Nivel de Sentencia

Oracle AI Database siempre aplica la consistencia de lectura de nivel de sentencia, lo que garantiza que los datos devueltos por una sola consulta se confirmen y sean coherentes durante un único momento.

El punto en el tiempo en el que una sola sentencia SQL es consistente depende del nivel de aislamiento de la transacción y de la naturaleza de la consulta:

Consulte también: Oracle AI Database Development Guide para obtener más información sobre la consulta de flashback

Consistencia de Lectura a Nivel de Transacción

Oracle AI Database también puede proporcionar consistencia de lectura a todas las consultas de una transacción, conocida como consistencia de lectura a nivel de transacción.

En este caso, cada sentencia de una transacción ve datos del mismo punto en el tiempo. Este es el momento en que comenzó la transacción.

Las consultas realizadas por una transacción serializable ven los cambios realizados por la propia transacción. Por ejemplo, una transacción que actualiza employees y, a continuación, consulta employees verá las actualizaciones. La consistencia de lectura a nivel de transacción produce lecturas repetibles y no expone una consulta a lecturas fantasma.

Leer segmentos de consistencia y deshacer

Para gestionar el modelo de consistencia de lectura de varias versiones, la base de datos debe crear un juego de datos de lectura consistente cuando se consulta y actualiza simultáneamente una tabla.

Oracle AI Database logra la consistencia de lectura mediante datos de deshacer.

Cada vez que un usuario modifica datos, Oracle AI Database crea entradas de deshacer, que escribe en segmentos de deshacer. Los segmentos de deshacer contienen los valores antiguos de datos que han cambiado las transacciones no confirmadas o confirmadas recientemente. Por lo tanto, pueden existir varias versiones de los mismos datos, todas en diferentes momentos en el tiempo, en la base de datos. La base de datos puede utilizar instantáneas de datos en diferentes momentos para proporcionar vistas de lectura consistente de los datos y activar consultas que no bloquean.

La consistencia de lectura está garantizada en entornos de instancia única y Oracle Real Application Clusters (Oracle RAC). Oracle RAC utiliza un mecanismo de transferencia de bloques de caché a caché conocido como fusión de caché para transferir imágenes de lectura consistente de bloques de datos de una instancia de base de datos a otra.

Consulte además:

Consistencia de Lectura: Ejemplo

En este ejemplo se muestra una consulta que utiliza datos de deshacer para proporcionar consistencia de lectura a nivel de sentencia en el nivel de aislamiento confirmado de lectura.

Figura 1: Consistencia de lectura en el nivel de aislamiento comprometido de lectura

Descripción de la ilustración cncpt069.gif

A medida que la base de datos recupera bloques de datos en nombre de una consulta, la base de datos garantiza que los datos de cada bloque reflejen el contenido del bloque cuando se inició la consulta. La base de datos realiza un rollback de los cambios en el bloque según sea necesario para reconstruir el bloque hasta el punto en que se inició el procesamiento de la consulta.

La base de datos utiliza un mecanismo de orden interno denominado SCN para garantizar el orden de las transacciones. A medida que la sentencia SELECT entra en la fase de ejecución, la base de datos determina el SCN registrado en el momento en que la consulta comenzó a ejecutarse. En la Figura 12-1, este SCN es 10023. La consulta solo ve datos confirmados con respecto al SCN 10023.

En la Figura 12-1, los bloques con SCN después de 10023 indican datos modificados, como muestran los dos bloques con SCN 10024. La sentencia SELECT necesita una versión del bloque que sea consistente con los cambios confirmados. La base de datos copia los bloques de datos actuales en un nuevo buffer y aplica datos de deshacer para reconstruir las versiones anteriores de los bloques. Estos bloques de datos reconstruidos se denominan clones de lectura consistente (CR).

En la Figura 12-1, la base de datos crea dos clones CR: un bloque consistente con SCN 10006 y el otro bloque consistente con SCN 10021. La base de datos devuelve los datos reconstruidos para la consulta. De esta forma, Oracle AI Database evita las lecturas sucias.

Consulte también: "Caché de Buffer de Base de Datos" y "Números de Cambio del Sistema (SCN)"

Leer listas de transacciones interesadas y de consistencia

La cabecera de bloque de cada bloque de segmento contiene una lista de transacciones interesadas (ITL).

La base de datos utiliza el ITL para determinar si una transacción no se ha confirmado cuando la base de datos comenzó a modificar el bloque.

Las entradas de ITL describen qué transacciones tienen filas bloqueadas y qué filas del bloque contienen cambios confirmados y sin confirmar. El ITL apunta a la tabla de transacciones en el segmento de deshacer, que proporciona información sobre el tiempo de los cambios realizados en la base de datos.

En cierto sentido, la cabecera de bloque contiene un historial reciente de transacciones que afectaron a cada fila del bloque. El parámetro INITRANS de las sentencias CREATE TABLE y ALTER TABLE controla el importe del historial de transacciones que se mantiene.

Consulte también: Referencia de lenguaje SQL de Oracle AI Database para obtener más información sobre el parámetro INITRANS

Consistencia de Lectura e Inserciones Diferidas

Un tipo especial de inserción conocido como inserción diferida no utiliza el mecanismo estándar de consistencia de lectura.

Una inserción diferida utiliza la indicación MEMOPTIMIZE_WRITE para insertar en una tabla especificada como MEMOPTIMIZE FOR WRITE. La base de datos almacena estas inserciones en el pool grande en lugar de en la caché de buffers. La base de datos no realiza un seguimiento de los cambios mediante redo y deshacer. En su lugar, la base de datos confirma automáticamente los cambios cuando el coordinador de gestión de espacio (SMCO) escribe el buffer en el disco. No se puede revertir el cambio.

Las inserciones diferidas difieren de las inserciones convencionales de maneras importantes:

Las aplicaciones cliente que deben evitar la pérdida de datos deben conservar una copia local de los datos después de escribir en el pool grande. El cliente puede utilizar el paquete DBMS_MEMOPTIMIZE para realizar un seguimiento de la durabilidad de las escrituras en la memoria y el paquete DBMS_MEMOPTIMIZE_ADMIN para forzar la escritura de la base de datos en el disco.

Consulte además:

Mecanismos de bloqueo

En general, las bases de datos de varios usuarios utilizan algún tipo de bloqueo de datos para resolver los problemas asociados a la simultaneidad, consistencia e integridad de los datos.

Un bloqueo es un mecanismo que evita la interacción destructiva entre transacciones que acceden al mismo recurso.

Consulte también: "Visión general del mecanismo de bloqueo de Oracle AI Database"

Niveles de aislamiento de transacciones ANSI/ISO

El estándar SQL, que ha sido adoptado por ANSI e ISO/IEC, define cuatro niveles de aislamiento de transacciones. Estos niveles tienen diferentes grados de impacto en el rendimiento global del procesamiento de transacciones.

Estos niveles de aislamiento se definen en términos de fenómenos que se deben evitar entre transacciones que se ejecutan simultáneamente. Los fenómenos prevenibles son:

El estándar SQL define cuatro niveles de aislamiento en términos de los fenómenos que puede experimentar una transacción que se ejecuta en un nivel de aislamiento concreto. La Tabla 12-1 muestra los niveles.

Tabla 1 Fenómenos de lectura prevenibles por nivel de aislamiento

Nivel de Aislamiento Lectura sucia Lectura no repetible Lectura fantasma
Lectura sin confirmar Posible Posible Posible
Lectura confirmada No es posible Posible Posible
Lectura Repetible No es posible No es posible Posible
Serializable No es posible No es posible No es posible

Oracle AI Database ofrece los niveles de aislamiento de lectura confirmada (por defecto) y serializable. Además, la base de datos ofrece un modo de solo lectura.

Consulte además:

Visión general de los niveles de aislamiento de transacciones de Oracle AI Database

El estándar ANSI para niveles de aislamiento de transacciones se define en términos de los fenómenos que se permiten o se evitan para cada nivel de aislamiento.

Oracle AI Database proporciona los niveles de aislamiento de transacciones:

Consulte además:

Leer nivel de aislamiento comprometido

En el nivel de aislamiento confirmado de lectura, cada consulta ejecutada por una transacción solo ve los datos confirmados antes de la consulta, no el inicio de la transacción.

Este nivel de aislamiento es el valor por defecto. Es adecuado para entornos de base de datos en los que es probable que haya pocas transacciones en conflicto.

Una consulta en una transacción confirmada de lectura evita la lectura de datos que se confirman mientras la consulta está en curso. Por ejemplo, si una consulta está a la mitad de una exploración de una tabla de millones de filas y si una transacción diferente confirma una actualización en la fila 950.000, la consulta no ve este cambio cuando lee la fila 950.000. Sin embargo, dado que la base de datos no impide que otras transacciones modifiquen los datos leídos por una consulta, otras transacciones pueden cambiar los datos entre las ejecuciones de la consulta. Por lo tanto, una transacción que ejecuta la misma consulta dos veces puede experimentar lecturas difusas y fantasmas.

Consistencia de Lectura en el Nivel de Aislamiento Confirmado de Lectura

La base de datos proporciona un juego de resultados consistente para cada consulta, lo que garantiza la consistencia de los datos, sin que el usuario realice ninguna acción.

Una consulta implícita, como una consulta implícita por una cláusula WHERE en una sentencia UPDATE, tiene garantizado un juego de resultados consistente. Sin embargo, cada sentencia de una consulta implícita no ve los cambios realizados por la propia sentencia DML, pero ve los datos como estaban antes de que se realizaran los cambios.

Si una lista SELECT contiene una función PL/SQL, la base de datos aplica consistencia de lectura de nivel de sentencia en el nivel de sentencia para la ejecución de SQL en el código de función PL/SQL, en lugar de en el nivel SQL principal. Por ejemplo, una función puede acceder a una tabla cuyos datos ha cambiado y confirmado otro usuario. Para cada ejecución de SELECT en la función, se establece una nueva instantánea de lectura consistente.

Consulte también: "Subconsultas"

Escrituras en conflicto en transacciones confirmadas leídas

En una transacción confirmada de lectura, se produce una escritura en conflicto cuando la transacción intenta cambiar una fila actualizada por una transacción simultánea sin confirmar.

La transacción que impide la modificación de filas a veces se denomina transacción de bloqueo. La transacción confirmada de lectura espera a que finalice la transacción de bloqueo y libere su bloqueo de fila.

Las opciones son las siguientes:

En la siguiente tabla se muestra cómo la transacción 1, que puede ser serializable o de lectura confirmada, interactúa con la transacción de lectura confirmada 2. Muestra una situación clásica conocida como actualización perdida. La actualización realizada por la transacción 1 no está en la tabla aunque la transacción 1 la haya confirmado. La elaboración de una estrategia para gestionar las actualizaciones perdidas es una parte importante del desarrollo de aplicaciones.

Tabla 2 Escrituras en conflicto y actualizaciones perdidas en una transacción READ COMMITTED

Sesión 1 Sesión 2 Explicación
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
  ('Banda', 'Greene',
 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6200
 Greene 9500 
No hay acción. La sesión 1 consulta los salarios de Banda, Greene e Hintz. No se ha encontrado ningún empleado denominado Hintz.
SQL> UPDATE employees
  SET salary = 7000 WHERE
  last_name = 'Banda';
No hay acción. La sesión 1 inicia una transacción actualizando el salario de Banda. El nivel de aislamiento por defecto para la transacción 1 es READ COMMITTED.
No hay acción.
SQL> SET TRANSACTION
  ISOLATION LEVEL
  READ COMMITTED;
La sesión 2 comienza la transacción 2 y define el nivel de aislamiento explícitamente en READ COMMITTED.
No hay acción.
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
 ('Banda', 'Greene',
 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6200
 Greene 9500
La transacción 2 consulta los salarios de Banda, Greene e Hintz. Oracle AI Database utiliza la consistencia de lectura para mostrar el salario de Banda antes de la actualización sin confirmar realizada por la transacción 1.
No hay acción.
SQL> UPDATE employees
  SET salary = 9900
  WHERE last_name='Greene';
La transacción 2 actualiza el salario de Greene correctamente porque la transacción 1 solo bloqueó la fila Banda.
SQL> INSERT INTO
  employees (employee_id,
  last_name, email,
  hire_date, job_id)
  VALUES (210, 'Hintz',
  'JHINTZ', SYSDATE,
  'SH_CLERK');
No hay acción. La transacción 1 inserta una fila para el empleado Hintz, pero no la confirma.
No hay acción.
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
  ('Banda', 'Greene',
 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6200
 Greene 9900

La transacción 2 consulta los salarios de los empleados Banda, Greene e Hintz.

La transacción 2 ve su propia actualización del salario de Greene. La transacción 2 no ve la actualización sin confirmar del salario de Banda ni la inserción de Hintz realizada por la transacción 1.

No hay acción.
SQL> UPDATE employees SET
 salary = 6300 WHERE
  last_name = 'Banda';

  -- prompt does not return 
La transacción 2 intenta actualizar la fila de Banda, que actualmente está bloqueada por la transacción 1, creando una escritura en conflicto. La transacción 2 espera hasta que finalice la transacción 1.
SQL> COMMIT;
No hay acción. La transacción 1 confirma su trabajo y finaliza la transacción.
No hay acción.
1 row updated.

  SQL>
El bloqueo de la fila Banda ahora se libera, por lo que la transacción 2 continúa con su actualización al salario de Banda.
No hay acción.
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
 ('Banda', 'Greene',
  'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6300
 Greene 9900
 Hintz
La transacción 2 consulta los salarios de los empleados Banda, Greene e Hintz. La inserción de Hintz confirmada por la transacción 1 ahora está visible para la transacción 2. La transacción 2 ve su propia actualización del salario de Banda.
No hay acción.
COMMIT;
La transacción 2 confirma su trabajo y finaliza la transacción.
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
  ('Banda', 'Greene',
 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6300
 Greene 9900
 Hintz
No hay acción. La sesión 1 consulta las filas de Banda, Greene e Hintz. El salario de Banda es de 6300, que es la actualización realizada por la transacción 2. La actualización del salario de Banda a 7000 realizada por la transacción 1 ahora es "perdida".

Consulte además:

Nivel de aislamiento serializable

En el nivel de aislamiento serializable, una transacción solo ve los cambios confirmados en el momento de la transacción, no el inicio de consulta y los cambios realizados por la propia transacción.

Una transacción serializable funciona en un entorno que hace que parezca como si ningún otro usuario estuviera modificando datos en la base de datos. El aislamiento serializable es adecuado para entornos:

En el aislamiento serializable, la consistencia de lectura normalmente obtenida en el nivel de sentencia se extiende a toda la transacción. Se garantiza que cualquier fila leída por la transacción será la misma cuando se vuelva a leer. Se garantiza que cualquier consulta devuelva los mismos resultados durante la transacción, por lo que los cambios realizados por otras transacciones no son visibles para la consulta independientemente del tiempo que se haya estado ejecutando. Las transacciones serializables no experimentan lecturas sucias, lecturas parciales o lecturas fantasma.

Oracle AI Database permite que una transacción serializable modifique una fila solo si los cambios en la fila realizados por otras transacciones ya se confirmaron cuando se inició la transacción serializable. La base de datos genera un error cuando una transacción serializable intenta actualizar o suprimir datos cambiados por otra transacción que se ha confirmado después de que se haya iniciado la transacción serializable:

ORA-08177: Cannot serialize access for this transaction

Cuando una transacción serializable falla con el error ORA-08177, una aplicación puede realizar varias acciones, incluidas las siguientes:

En la siguiente tabla se muestra cómo una transacción serializable interactúa con otras transacciones. Si la transacción serializable no intenta cambiar una fila confirmada por otra transacción después de que se inició la transacción serializable, se evita un problema de acceso serializado.

Tabla 3 Transacción serializable

Sesión 1 Sesión 2 Explicación
SQL> SELECT last_name, salary FROM employees WHERE
  last_name IN ('Banda',
  'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 6200
 Greene 9500
No hay acción. La sesión 1 consulta los salarios de Banda, Greene e Hintz. No se ha encontrado ningún empleado denominado Hintz.
SQL> UPDATE employees
  SET salary = 7000
  WHERE last_name='Banda';
No hay acción. La sesión 1 inicia la transacción 1 actualizando el salario de Banda. El nivel de aislamiento por defecto es READ COMMITTED.
No hay acción.
SQL> SET TRANSACTION
  ISOLATION LEVEL SERIALIZABLE;
La sesión 2 comienza la transacción 2 y la define en el nivel de aislamiento SERIALIZABLE.
No hay acción.
SQL> SELECT last_name, salary FROM employees
  WHERE last_name IN
  ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------ ----------
 Banda 6200
 Greene 9500
La transacción 2 consulta los salarios de Banda, Greene e Hintz. Oracle AI Database utiliza la consistencia de lectura para mostrar el salario de Banda antes de la actualización sin confirmar realizada por la transacción 1.
No hay acción.
SQL> UPDATE employees
  SET salary = 9900
  WHERE last_name = 'Greene';
La transacción 2 actualiza el salario Greene correctamente porque solo se bloquea la fila Banda.
SQL> INSERT INTO employees
  (employee_id, last_name,
  email, hire_date, job_id)
  VALUES (210, 'Hintz',
  'JHINTZ', SYSDATE,'SH_CLERK');
No hay acción. La transacción 1 inserta una fila para el empleado Hintz.
SQL> COMMIT;
No hay acción. La transacción 1 confirma su trabajo y finaliza la transacción.
SQL> SELECT last_name, salary
  FROM employees
  WHERE last_name IN
  ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 7000
 Greene 9500
 Hintz
SQL> SELECT last_name, salary FROM employees
  WHERE last_name IN
 ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ---------
 Banda 6200
 Greene 9900

La sesión 1 consulta los salarios de los empleados Banda, Greene e Hintz y ve los cambios confirmados por la transacción 1. La sesión 1 no ve la actualización de Greene sin confirmar realizada por la transacción 2.

La transacción 2 consulta los salarios de los empleados Banda, Greene e Hintz. La consistencia de lectura de Oracle AI Database garantiza que la inserción de Hintz y la actualización de Banda confirmadas por la transacción 1 no sean visibles para la transacción 2. La transacción 2 ve su propia actualización del salario de Greene.

No hay acción.
COMMIT;
La transacción 2 confirma su trabajo y finaliza la transacción.
SQL> SELECT last_name, salary
  FROM employees
  WHERE last_name IN
  ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 7000
 Greene 9900
 Hintz
SQL> SELECT last_name, salary
 FROM employees
  WHERE last_name IN
  ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ---------
 Banda 7000
 Greene 9900
 Hintz
Ambas sesiones consultan los salarios de Banda, Greene e Hintz. Cada sesión ve todos los cambios confirmados realizados por la transacción 1 y la transacción 2.
SQL> UPDATE employees
  SET salary = 7100
  WHERE last_name = 'Hintz';
No hay acción. La sesión 1 inicia la transacción 3 actualizando el salario de Hintz. El nivel de aislamiento por defecto para la transacción 3 es READ COMMITTED.
No hay acción.
SQL> SET TRANSACTION
  ISOLATION LEVEL SERIALIZABLE;
La sesión 2 comienza la transacción 4 y la define en el nivel de aislamiento SERIALIZABLE.
No hay acción.
SQL> UPDATE employees
  SET salary = 7200
  WHERE last_name = 'Hintz';

  -- prompt does not return
La transacción 4 intenta actualizar el salario de Hintz, pero está bloqueada porque la transacción 3 bloqueó la fila de Hintz. Las colas de la transacción 4 detrás de la transacción 3.
SQL> COMMIT;
No hay acción. La transacción 3 confirma la actualización del salario de Hintz y finaliza la transacción.
No hay acción.
UPDATE employees
  SET salary = 7200
  WHERE last_name = 'Hintz'
 *
 ERROR at line 1:
  ORA-08177: can't
  serialize access for
  this transaction
La confirmación que finaliza la transacción 3 hace que la actualización de Hintz en la transacción 4 falle y se produzca el error ORA-08177. El error de problema se produce porque la transacción 3 confirmó la actualización de Hintz después de que la transacción 4 comenzara.
No hay acción.
SQL> ROLLBACK;
La sesión 2 realiza un rollback de la transacción 4, que finaliza la transacción.
No hay acción.
SQL> SET TRANSACTION
  ISOLATION LEVEL SERIALIZABLE;
La sesión 2 inicia la transacción 5 y la define en el nivel de aislamiento SERIALIZABLE.
No hay acción.
SQL> SELECT last_name,
  salary FROM employees
  WHERE last_name IN
  ('Banda', 'Greene', 'Hintz');

  LAST_NAME SALARY
 ------------- ----------
 Banda 7000
 Greene 9900
 Hintz 7100
La transacción 5 consulta los salarios de Banda, Greene e Hintz. La actualización salarial de Hintz confirmada por la transacción 3 está visible.
No hay acción.
SQL> UPDATE employees
  SET salary = 7200
  WHERE last_name='Hintz';

  1 row updated.

La transacción 5 actualiza el salario de Hintz a un valor diferente. Debido a que la actualización de Hintz realizada por la transacción 3 se confirmó antes del inicio de la transacción 5, se evita el problema de acceso serializado.

Nota: Si una transacción diferente actualiza y confirma la fila Hintz después de iniciar la transacción 5, el problema de acceso serializado se volvería a producir.

No hay acción.
SQL> COMMIT; 
La sesión 2 confirma la actualización sin ningún problema y finaliza la transacción.

Consulte además:

Nivel de aislamiento de solo lectura

El nivel de aislamiento de solo lectura es similar al nivel de aislamiento serializable, pero las transacciones de solo lectura no permiten que los datos se modifiquen en la transacción a menos que el usuario sea SYS.

Las transacciones de solo lectura no son susceptibles al error ORA-08177. Las transacciones de sólo lectura son útiles para generar informes en los que el contenido debe ser coherente con respecto a la hora en que comenzó la transacción.

Oracle AI Database logra la consistencia de lectura al reconstruir los datos según sea necesario a partir de los segmentos de deshacer. Puesto que los segmentos de deshacer se utilizan de forma circular, la base de datos puede sobrescribir los datos de deshacer. Los informes de larga ejecución corren el riesgo de que una transacción diferente haya reutilizado los datos de deshacer necesarios para la consistencia de lectura, lo que genera un error snapshot too old. Al definir un período de retención de deshacer, que es la cantidad mínima de tiempo que la base de datos intenta retener los datos de deshacer antiguos antes de sobrescribirlos, se evita este problema de manera adecuada.

Consulte además:

Visión general del mecanismo de bloqueo de Oracle AI Database

Un bloqueo es un mecanismo que evita interacciones destructivas.

Las interacciones son destructivas cuando actualizan datos incorrectamente o modifican incorrectamente las estructuras de datos subyacentes, entre transacciones que acceden a datos compartidos. Los bloqueos desempeñan un papel crucial en el mantenimiento de la simultaneidad y coherencia de la base de datos.

Resumen del comportamiento de bloqueo

La base de datos mantiene varios tipos diferentes de bloqueos, según la operación que haya adquirido el bloqueo.

En general, la base de datos utiliza dos tipos de bloqueos: los bloqueos exclusivos y los bloqueos compartidos. Solo se puede obtener un bloqueo exclusivo en un recurso, como una fila o una tabla, pero se pueden obtener muchos bloqueos de recursos compartidos en un único recurso.

Las cerraduras afectan la interacción de lectores y escritores. Un lector es una consulta de un recurso, mientras que un escritor es una sentencia que modifica un recurso. Las siguientes reglas resumen el comportamiento de bloqueo de Oracle AI Database para lectores y escritores:

Consulte además:

Uso de bloqueos

En una base de datos de un solo usuario, los bloqueos no son necesarios porque solo un usuario está modificando la información. Sin embargo, cuando varios usuarios acceden y modifican datos, la base de datos debe proporcionar una forma de evitar la modificación simultánea de los mismos datos.

Los bloqueos cumplen los siguientes requisitos importantes de la base de datos:

Oracle AI Database proporciona simultaneidad, consistencia e integridad de datos entre las transacciones a través de sus mecanismos de bloqueo. El bloqueo se produce automáticamente y no requiere ninguna acción del usuario.

La necesidad de bloqueos se puede ilustrar mediante una actualización simultánea de una sola fila. En el siguiente ejemplo, una sencilla aplicación basada en web presenta al usuario final un correo electrónico y un número de teléfono del empleado. La aplicación utiliza una sentencia UPDATE como la siguiente para modificar los datos:

UPDATE employees
SET    email = ?, phone_number = ?
WHERE  employee_id = ?
AND    email = ?
AND    phone_number = ?

En la sentencia UPDATE anterior, los valores de correo electrónico y número de teléfono de la cláusula WHERE son los valores originales sin modificar para el empleado especificado. Esta actualización garantiza que la fila que modifica la aplicación no se haya cambiado después de la última lectura de la aplicación y se haya mostrado al usuario. De esta forma, la aplicación evita el problema de actualización perdida en el que un usuario sobrescribe los cambios realizados por otro usuario, perdiendo efectivamente la actualización por el segundo usuario (la Tabla 12-2 muestra un ejemplo de una actualización perdida). La Tabla 12-4 muestra la secuencia de eventos cuando dos sesiones intentan modificar la misma fila en la tabla employees aproximadamente al mismo tiempo.

Tabla 4: Ejemplo de bloqueo de filas

T Sesión 1 Sesión 2 Descripción
t0
SELECT employee_id as ID,
  email, phone_number
  FROM hr.employees
  WHERE last_name='Himuro';
ID EMAIL PHONE_NUMBER
 --- ------- ------------
 118 GHIMURO 515.127.4565
  En la sesión 1, el usuario hr1 consulta hr.employees para el registro de Himuro y muestra los atributos employee_id (118), correo electrónico (GHIMURO) y número de teléfono (515.127.4565).
t1  
SELECT employee_id as ID,
 email, phone_number
  FROM hr.employees
  WHERE last_name='Himuro';
ID EMAIL PHONE_NUMBER
 --- ------- ------------
 118 GHIMURO 515.127.4565
En la sesión 2, el usuario hr2 consulta hr.employees para el registro Himuro y muestra los atributos employee_id (118), correo electrónico (GHIMURO) y número de teléfono (515.127.4565).
t2
UPDATE hr.employees SET
  phone_number='515.555.1234'
 WHERE employee_id=118
 AND email='GHIMURO'
 AND phone_number =
  '515.127.4565';

  1 row updated.
  En la sesión 1, el usuario hr1 actualiza el número de teléfono de la fila a 515.555.1234, que adquiere un bloqueo en la fila GHIMURO.
t3  
UPDATE hr.employees SET
  phone_number='515.555.1235'
 WHERE employee_id=118
 AND email='GHIMURO'
 AND phone_number =
  '515.127.4565';

  -- SQL*Plus does not show
 -- a row updated message or
 -- return the prompt.

En la sesión 2, el usuario hr2 intenta actualizar la misma fila, pero se bloquea porque hr1 está procesando actualmente la fila.

El intento de actualización por parte de hr2 se produce casi simultáneamente con la actualización hr1.

t4
COMMIT;

  Commit complete.
 

En la sesión 1, el usuario hr1 confirma la transacción.

El compromiso hace que el cambio para Himuro sea permanente y desbloquea la sesión 2, que ha estado esperando.

t5  
0 rows updated.

En la sesión 2, el usuario hr2 detecta que la fila GHIMURO se ha modificado de forma que ya no coincida con su predicado.

Puesto que los predicados no coinciden, la sesión 2 no actualiza ningún registro.

t6
UPDATE hr.employees SET
  phone_number='515.555.1235'
 WHERE employee_id=118
 AND email='GHIMURO' AND
  phone_number='515.555.1234';

  1 row updated.
  En la sesión 1, el usuario hr1 se da cuenta de que ha actualizado la fila GHIMURO con el número de teléfono incorrecto. El usuario inicia una nueva transacción y actualiza el número de teléfono de la fila a 515.555.1235, que bloquea la fila GHIMURO.
t7  
SELECT employee_id as ID,
  email, phone_number
  FROM hr.employees
  WHERE last_name='Himuro';
ID EMAIL PHONE_NUMBER
 --- ------- ------------
 118 GHIMURO 515.555.1234
En la sesión 2, el usuario hr2 consulta hr.employees para el registro de Himuro. El registro muestra la actualización del número de teléfono confirmada por la sesión 1 en t4. La consistencia de lectura de Oracle AI Database garantiza que la sesión 2 no vea los cambios sin confirmar realizados en t6.
t8  
UPDATE hr.employees SET
  phone_number='515.555.1235
  WHERE employee_id=118
 AND email='GHIMURO'
 AND phone_number =
 '515.555.1234';

  -- SQL*Plus does not show
 -- a row updated message or
 -- return the prompt.
En la sesión 2, el usuario hr2 intenta actualizar la misma fila, pero se bloquea porque hr1 está procesando actualmente la fila.
t9
ROLLBACK;

  Rollback complete.
  En la sesión 1, el usuario hr1 realiza un rollback de la transacción, que la termina.
t10  
1 row updated.
En la sesión 2, la actualización del número de teléfono se realiza correctamente porque se realizó un rollback de la actualización de la sesión 1. La fila GHIMURO coincide con su predicado, por lo que la actualización se realiza correctamente.
t11  
COMMIT;

  Commit complete.
La sesión 2 confirma la actualización y finaliza la transacción.

Oracle AI Database obtiene automáticamente los bloqueos necesarios al ejecutar sentencias SQL. Por ejemplo, antes de que la base de datos permita que una sesión modifique datos, la sesión primero debe bloquear los datos. El bloqueo otorga a la sesión control exclusivo sobre los datos para que ninguna otra transacción pueda modificar los datos bloqueados hasta que se libere el bloqueo.

Debido a que los mecanismos de bloqueo de Oracle AI Database están estrechamente vinculados al control de transacciones, los diseñadores de aplicaciones solo necesitan definir las transacciones correctamente, y Oracle AI Database gestiona automáticamente el bloqueo. Los usuarios nunca necesitan bloquear ningún recurso de forma explícita, aunque Oracle AI Database también permite a los usuarios bloquear datos manualmente.

En las siguientes secciones se explican los conceptos que son importantes para comprender cómo Oracle AI Database logra la simultaneidad de datos.

Consulte también: Referencia de tipos y paquetes PL/SQL de Oracle AI Database para obtener más información sobre el paquete OWA_OPT_LOCK, que contiene subprogramas que pueden ayudar a evitar actualizaciones perdidas

Modos de bloqueo

Oracle AI Database utiliza automáticamente el nivel aplicable menor de restricción para proporcionar el mayor grado de concurrencia de datos al mismo tiempo, además de proporcionar una integridad de datos con seguridad de fallos.

Cuanto menos restrictivo sea el nivel, más disponibles estarán los datos para el acceso de otros usuarios. Por el contrario, cuanto más restrictivo sea el nivel, más limitadas serán las otras transacciones en los tipos de bloqueos que pueden adquirir.

Oracle AI Database utiliza dos modos de bloqueo en una base de datos de varios usuarios:

Supongamos que una transacción utiliza una sentencia SELECT ... FOR UPDATE para seleccionar una única fila de tabla. La transacción adquiere un bloqueo de fila exclusivo y un bloqueo de tabla de uso compartido de filas. El bloqueo de filas permite que otras sesiones modifiquen cualquier fila que no sea la fila bloqueada, mientras que el bloqueo de la tabla evita que las sesiones modifiquen la estructura de la tabla. Por lo tanto, la base de datos permite ejecutar tantas sentencias como sea posible.

Bloquear conversión y escalada

Oracle AI Database realiza la conversión de bloqueos según sea necesario.

En la conversión de bloqueo, la base de datos convierte automáticamente un bloqueo de tabla de menor restricción a uno de mayor restricción. Por ejemplo, supongamos que una transacción emite un SELECT ... FOR UPDATE para un empleado y, posteriormente, actualiza la fila bloqueada. En este caso, la base de datos convierte automáticamente el bloqueo de tabla compartida de filas en un bloqueo de tabla exclusivo de filas. Una transacción contiene bloqueos de filas exclusivos para todas las filas insertadas, actualizadas o eliminadas dentro de la transacción. Puesto que los bloqueos de fila se adquieren con el mayor grado de restricción, no es necesaria ni se realiza ninguna conversión de bloqueo.

La conversión de bloqueos es diferente de la escalada de bloqueos, que se produce cuando varios bloqueos se mantienen en un nivel de granularidad (por ejemplo, filas) y una base de datos eleva los bloqueos a un nivel de granularidad superior (por ejemplo, tabla). Si una sesión bloquea muchas filas en una tabla, algunas bases de datos escalan automáticamente los bloqueos de filas a una sola tabla. El número de bloqueos disminuye, pero la restricción de lo que está bloqueado aumenta.

Oracle AI Database nunca escala los bloqueos. La escalada de bloqueo aumenta considerablemente la probabilidad de interbloqueos. Supongamos que un sistema está intentando escalar bloqueos en nombre de la transacción 1, pero no puede deberse a los bloqueos retenidos por la transacción 2. Se crea un interbloqueo si la transacción 2 también necesita la escalada de bloqueo de los mismos datos para poder continuar.

Duración de bloqueo

Oracle AI Database libera automáticamente un bloqueo cuando se produce algún evento para que la transacción ya no necesite el recurso.

Normalmente, la base de datos contiene bloqueos adquiridos por sentencias dentro de una transacción durante el tiempo que dure la transacción. Estos bloqueos evitan interferencias destructivas, como lecturas sucias, actualizaciones perdidas y DDL destructivas de transacciones simultáneas. Nota: Un bloqueo de tabla aplicado a una tabla secundaria debido a una clave ajena no indexada se mantiene durante la sentencia, no durante la transacción. Además, el paquete DBMS_LOCK permite que los bloqueos definidos por el usuario se liberen y asignen a voluntad e incluso se retengan sobre los límites de la transacción.

Oracle AI Database libera todos los bloqueos adquiridos por las sentencias de una transacción cuando se confirma o se realiza un rollback. Oracle AI Database también libera bloqueos adquiridos después de un punto de grabación al realizar un rollback al punto de grabación. Sin embargo, solo las transacciones que no esperan los recursos bloqueados anteriormente pueden adquirir bloqueos en los recursos ahora disponibles. Las transacciones en espera siguen esperando hasta que la transacción original se confirme o realice un rollback por completo.

Consulte además:

Bloqueos e Interbloqueos

Un bloqueo es una situación en la que dos o más usuarios están esperando datos bloqueados entre sí. Los interbloqueos impiden que algunas transacciones sigan funcionando.

Oracle AI Database detecta automáticamente interbloqueos y los resuelve realizando un rollback de una sentencia implicada en el interbloqueo, liberando un juego de bloqueos de fila en conflicto. La base de datos devuelve un mensaje correspondiente a la transacción que se somete a rollback de nivel de sentencia. La sentencia de la que se ha realizado un rollback pertenece a la transacción que detecta el interbloqueo. Normalmente, se debe realizar un rollback de la transacción indicada de forma explícita, pero puede volver a intentar la sentencia de rollback después de esperar. La Tabla 12-5 ilustra dos transacciones en un interbloqueo.

Tabla 5 Transacciones con interbloqueo

T Sesión 1 Sesión 2 Explicación
t0
SQL> UPDATE employees
  SET salary = salary*1.1
 WHERE employee_id = 100;

  1 row updated.
SQL> UPDATE employees
 SET salary = salary*1.1
 WHERE employee_id = 200;

  1 row updated.
La sesión 1 inicia la transacción 1 y actualiza el salario del empleado 100. La sesión 2 inicia la transacción 2 y actualiza el salario del empleado 200. No existe ningún problema porque cada transacción bloquea solo la fila que intenta actualizar.
t1
SQL> UPDATE employees
  SET salary = salary*1.1
 WHERE employee_id = 200;

  -- prompt does not return
SQL> UPDATE employees
 SET salary = salary*1.1
 WHERE employee_id = 100;

  -- prompt does not return

La transacción 1 intenta actualizar la fila 200 del empleado, que actualmente está bloqueada por la transacción 2. La transacción 2 intenta actualizar la fila 100 del empleado, que actualmente está bloqueada por la transacción 1.

Se produce un interbloqueo porque ninguna transacción puede obtener el recurso que necesita para continuar o terminar. No importa cuánto tiempo espere cada transacción, los bloqueos en conflicto se mantienen.

t2
UPDATE employees
 *
 ERROR at line 1:
 ORA-00060: deadlock detected
 while waiting for resource

  SQL>
 

La transacción 1 señala el interbloqueo y revierte la sentencia UPDATE emitida en t1. Sin embargo, no se realiza un rollback de la actualización realizada en t0. El indicador se devuelve en la sesión 1.

Nota: Sólo una sesión en el interbloqueo obtiene el error de interbloqueo, pero cualquiera de las sesiones puede obtener el error.

t3
SQL> COMMIT;

  Commit complete.
  La sesión 1 confirma la actualización realizada en t0, finalizando la transacción 1. La actualización que se intentó correctamente en t1 no se ha confirmado.
t4  
1 row updated.

  SQL>
Se ejecuta la actualización en t1 en la transacción 2, que estaba siendo bloqueada por la transacción 1. Se devuelve el mensaje.
t5  
SQL> COMMIT;

  Commit complete.
La sesión 2 confirma las actualizaciones realizadas en t0 y t1, que finalizan la transacción 2.

Los interbloqueos se producen con mayor frecuencia cuando las transacciones sustituyen explícitamente el bloqueo por defecto de Oracle AI Database. Debido a que Oracle AI Database no escala los bloqueos y no utiliza bloqueos de lectura para las consultas, sino que utiliza el bloqueo a nivel de fila (en lugar de a nivel de página), los interbloqueos se producen con poca frecuencia.

Consulte además:

Descripción general de Bloqueos automáticos

Oracle AI Database bloquea automáticamente un recurso en nombre de una transacción para evitar que otras transacciones realicen algo que requiera acceso exclusivo al mismo recurso.

La base de datos adquiere automáticamente diferentes tipos de bloqueos en diferentes niveles de restricción según el recurso y la operación que se esté realizando. Nota: La base de datos nunca bloquea filas al realizar lecturas simples.

Los bloqueos de Oracle AI Database se dividen en las categorías que se muestran en la siguiente tabla.

Tabla 6 Categorías de bloqueo

Bloquear Descripción Para saber más
Bloqueos de DML Proteja los datos. Por ejemplo, los bloqueos de tabla bloquean tablas completas, mientras que los bloqueos de fila bloquean filas seleccionadas. "Bloques de DML"
Bloqueos de DDL Proteger la estructura de los objetos de esquema, por ejemplo, las definiciones de diccionario de tablas y vistas. "Bloques de DDL"
Bloqueos del sistema Proteja las estructuras de bases de datos internas, como los archivos de datos. Los bloqueos internos, los mutex y los bloqueos internos son completamente automáticos. "System Locks" (Bloques del sistema)

Bloqueos de DML

Un bloqueo de DML, también denominado bloqueo de datos, garantiza la integridad de los datos a los que acceden simultáneamente varios usuarios.

Por ejemplo, un bloqueo DML impide que dos clientes compren la última copia de un libro disponible de un librero en línea. Los bloqueos DML evitan que se produzcan interferencias destructivas de las operaciones DML o DDL simultáneas.

Las sentencias DML adquieren automáticamente los siguientes tipos de bloqueos:

En las siguientes secciones, el acrónimo entre paréntesis después de cada tipo de bloqueo o modo de bloqueo es la abreviatura utilizada en la supervisión de bloqueos de Oracle Enterprise Manager (Enterprise Manager). Enterprise Manager puede mostrar TM para cualquier bloqueo de tabla, en lugar de indicar el modo de bloqueo de tabla (como RS o SRX).

Bloqueos de fila (TX)

Un bloqueo de fila, también denominado bloqueo de TX, es un bloqueo en una sola fila de tabla. Una transacción adquiere un bloqueo de fila para cada fila modificada por una sentencia INSERT, UPDATE, DELETE, MERGE o SELECT ... FOR UPDATE. El bloqueo de fila existe hasta que la transacción se confirma o se realiza un rollback.

Los bloqueos de fila sirven principalmente como mecanismo de cola para evitar que dos transacciones modifiquen la misma fila. La base de datos siempre bloquea una fila modificada en modo exclusivo para que otras transacciones no puedan modificar la fila hasta que la transacción que retiene el bloqueo se confirme o realice un rollback. El bloqueo de filas proporciona el mejor bloqueo de grano posible y, por lo tanto, proporciona la mejor simultaneidad y rendimiento posibles.

Nota: Si una transacción termina debido a un fallo de instancia de la base de datos, la recuperación a nivel de bloque hace que una fila esté disponible antes de que se recupere toda la transacción.

Si una transacción obtiene un bloqueo para una fila, la transacción también adquiere un bloqueo para la tabla que contiene la fila. El bloqueo de tabla evita operaciones DDL en conflicto que sustituirían los cambios de datos en una transacción actual. La Figura 12-2 ilustra una actualización de la tercera fila de una tabla. Oracle AI Database coloca automáticamente un bloqueo exclusivo en la fila actualizada y un bloqueo subexclusivo en la tabla.

Figura 2: Bloqueos de Fila y Tabla

Descripción de la ilustración cncpt265.gif

Bloqueos de Fila y Simultaneidad

Este escenario ilustra cómo Oracle AI Database utiliza bloqueos de filas para simultaneidad.

Tres sesiones consultan las mismas filas simultáneamente. Las sesiones 1 y 2 continúan realizando actualizaciones sin confirmar en diferentes filas, mientras que la sesión 3 no realiza ninguna actualización. Cada sesión ve sus propias actualizaciones sin confirmar, pero no las actualizaciones sin confirmar de cualquier otra sesión.

Tabla 7 Ejemplo de simultaneidad de datos

T Sesión 1 Sesión 2 Sesión 3 Explicación
t0
SELECT employee_id,
 salary
 FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
SELECT employee_id,
 salary
  FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
SELECT employee_id,
  salary
  FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
Tres sesiones diferentes consultan simultáneamente el ID y el salario de los empleados 100 y 101. Los resultados devueltos por cada consulta son idénticos.
t1
UPDATE hr.employees
 SET salary =
  salary+100
 WHERE
  employee_id=100;
    La sesión 1 actualiza el salario del empleado 100, pero no confirma. En la actualización, el escritor adquiere un bloqueo de nivel de fila solo para la fila actualizada, lo que impide que otros escritores modifiquen esta fila.
t2
SELECT employee_id,
 salary
  FROM employees
  WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 612
 101 600
SELECT employee_id,
 salary
 FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
SELECT employee_id,
  salary
  FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
Cada sesión emite simultáneamente la consulta original. La sesión 1 muestra el salario de 612 resultante de la actualización t1. Los lectores de la sesión 2 y 3 devuelven filas inmediatamente y no esperan a que la sesión 1 finalice su transacción. La base de datos utiliza la consistencia de lectura de varias versiones para mostrar el salario tal y como existía antes de la actualización en la sesión 1.
t3  
UPDATE hr.employee
 SET salary =
 salary+100
 WHERE
  employee_id=101;
  La sesión 2 actualiza el salario del empleado 101, pero no confirma la transacción. En la actualización, el escritor adquiere un bloqueo de nivel de fila solo para la fila actualizada, lo que impide que otros escritores modifiquen esta fila.
t4
SELECT employee_id,
 salary
  FROM employees
  WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 612
 101 600
SELECT employee_id,
 salary
 FROM employees
  WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 700
SELECT employee_id,
  salary
  FROM employees
 WHERE employee_id
 IN ( 100, 101 );
EMPLOYEE_ID SALARY
 ----------- ------
 100 512
 101 600
Cada sesión emite simultáneamente la consulta original. La sesión 1 muestra el salario de 612 resultante de la actualización t1, pero no la actualización de salario del empleado 101 realizada en la sesión 2. El lector de la sesión 2 muestra la actualización salarial realizada en la sesión 2, pero no la actualización salarial realizada en la sesión 1. El lector en la sesión 3 utiliza la consistencia de lectura para mostrar los salarios antes de la modificación por sesión 1 y 2.

Consulte además:

Almacenamiento de bloqueos de fila

A diferencia de algunas bases de datos, que utilizan un gestor de bloqueo para mantener una lista de bloqueos en la memoria, Oracle AI Database almacena información de bloqueo en el bloque de datos que contiene la fila bloqueada.

La base de datos utiliza un mecanismo de cola para la adquisición de bloqueos de fila. Si una transacción necesita un bloqueo para una fila desbloqueada, la transacción coloca un bloqueo en el bloque de datos. Cada fila modificada por esta transacción apunta a una copia del ID de transacción almacenado en la cabecera de bloque.

Cuando finaliza una transacción, el ID de transacción permanece en la cabecera del bloque. Si una transacción distinta desea modificar una fila, utiliza el ID de transacción para determinar si el bloqueo está activo. Si el bloqueo está activo, la sesión solicita que se le notifique cuando se libera el bloqueo. De lo contrario, la transacción adquiere el bloqueo.

Consulte además:

Bloqueos de tabla (TM)

Un bloqueo de tabla, también denominado bloqueo TM, se adquiere mediante una transacción cuando una tabla se modifica mediante una sentencia INSERT, UPDATE, DELETE, MERGE, SELECT con la cláusula FOR UPDATE o LOCK TABLE.

Las operaciones DML necesitan bloqueos de tabla para reservar el acceso DML a la tabla en nombre de una transacción y para evitar operaciones DDL que entren en conflicto con la transacción.

Un bloqueo de tabla se puede mantener en cualquiera de los siguientes modos:

Consulte además:

Bloqueos y claves ajenas

Oracle AI Database maximiza el control de simultaneidad de las claves principales en relación con las claves ajenas dependientes.

El comportamiento de bloqueo depende de si las columnas de clave ajena están indexadas. Si no se indexan las claves ajenas, es probable que la tabla secundaria se bloquee con más frecuencia, se produzcan interbloqueos y disminuya la simultaneidad. Por este motivo, las claves ajenas casi siempre se deben indexar. La única excepción es cuando la clave única o primaria coincidente nunca se actualiza ni se suprime.

Bloqueos y Claves Ajenas No Indexadas

La base de datos adquiere un bloqueo de tabla completo en la tabla secundaria cuando no existe ningún índice en la columna de clave ajena de la tabla secundaria y una sesión modifica una clave primaria en la tabla principal (por ejemplo, suprime una fila o modifica los atributos de clave primaria) o fusiona filas en la tabla principal.

Cuando se cumplen las dos condiciones siguientes, la base de datos adquiere un bloqueo de tabla completo en la tabla secundaria:

Supongamos que la tabla hr.departments es un principal de hr.employees, que contiene la clave ajena no indexada employees.department_id. En la siguiente figura se muestra una sesión que modifica los atributos de clave primaria del departamento 60 en la tabla departments.

Figura 3: Mecanismos de bloqueo con clave ajena no indexada

Descripción de la ilustración cncpt308.gif

En la Figura 12-3, la base de datos adquiere un bloqueo de tabla completo en employees durante la modificación de clave primaria del departamento 60. Este bloqueo permite a otras sesiones consultar pero no actualizar la tabla employees. Por ejemplo, las sesiones no pueden actualizar los números de teléfono de los empleados. El bloqueo de tabla en las versiones employees inmediatamente después de que se complete la modificación de clave primaria en la tabla departments. Si varias filas de departments sufren modificaciones de clave primaria, se obtiene y libera un bloqueo de tabla en employees una vez para cada fila que se modifica en departments. Nota: DML en una tabla secundaria no adquiere un bloqueo de tabla en la tabla principal.

Bloqueos y Claves Ajenas Indexadas

La base de datos no adquiere un bloqueo de tabla completo en la tabla secundaria cuando una columna de clave ajena de la tabla secundaria está indexada, y una sesión modifica una clave primaria de la tabla principal (por ejemplo, suprime una fila o modifica los atributos de clave primaria) o fusiona filas en la tabla principal.

Un bloqueo en la tabla principal impide que las transacciones adquieran bloqueos exclusivos de la tabla, pero no impide que DML en la tabla secundaria o principal durante la modificación de la clave primaria. Esta situación es preferible si se producen modificaciones de clave primaria en la tabla principal mientras que las actualizaciones se producen en la tabla secundaria. La Figura 12-4 muestra la tabla secundaria employees con una columna department_id indexada. Una transacción suprime el departamento 280 de departments. Esta supresión no hace que la base de datos adquiera un bloqueo de tabla completo en la tabla employees como en el escenario descrito en "Bloques y Claves Ajenas No Indexadas".

Figura 4: Mecanismos de Bloqueo con Clave Ajena Indexada

Descripción de la ilustración cncpt309.gif

Si la tabla secundaria especifica ON DELETE CASCADE, las supresiones de la tabla principal pueden dar lugar a supresiones de la tabla secundaria. Por ejemplo, la eliminación del departamento 280 puede provocar la eliminación de registros de employees para los empleados del departamento suprimido. En este caso, las reglas de espera y bloqueo son las mismas que si suprimiera filas de la tabla secundaria después de suprimir filas de la tabla principal.

Consulte además:

Bloqueos de DDL

Un bloqueo del diccionario de datos (DDL) protege la definición de un objeto de esquema mientras que una operación DDL en curso actúa sobre el objeto o hace referencia a él.

Solo los objetos de esquema individuales que se modifican o a los que se hace referencia se bloquean durante las operaciones DDL. La base de datos nunca bloquea todo el diccionario de datos.

Oracle AI Database adquiere automáticamente un bloqueo DDL en nombre de cualquier transacción DDL que lo necesite. Los usuarios no pueden solicitar bloqueos DDL de forma explícita. Por ejemplo, si un usuario crea un procedimiento almacenado, Oracle AI Database adquiere automáticamente bloqueos DDL para todos los objetos de esquema a los que se hace referencia en la definición del procedimiento. Los bloqueos DDL impiden que estos objetos se modifiquen o borren antes de que se complete la compilación del procedimiento.

Bloqueos DDL Exclusivos

Un bloqueo DDL exclusivo impide que otras sesiones obtengan un bloqueo DDL o DML.

La mayoría de las operaciones DDL requieren bloqueos DDL exclusivos para un recurso a fin de evitar interferencias destructivas con otras operaciones DDL que puedan modificar o hacer referencia al mismo objeto de esquema. Por ejemplo, DROP TABLE no puede borrar una tabla mientras ALTER TABLE le agrega una columna y viceversa.

Los bloqueos DDL exclusivos duran la ejecución de la sentencia DDL y la confirmación automática. Durante la adquisición de un bloqueo DDL exclusivo, si otra operación mantiene otro bloqueo DDL en el objeto de esquema, la adquisición espera hasta que se libere el bloqueo DDL anterior y, a continuación, continúa.

Consulte también: "Compartir bloqueos DDL" describe situaciones en las que no se necesitan bloqueos exclusivos para evitar interferencias destructivas

Compartir bloqueos de DDL

Un bloqueo de DDL de recurso compartido para un recurso evita interferencias destructivas con operaciones DDL en conflicto, pero permite la simultaneidad de datos para operaciones DDL similares.

Por ejemplo, cuando se ejecuta una sentencia CREATE PROCEDURE, la transacción que contiene adquiere bloqueos DDL compartidos para todas las tablas a las que se hace referencia. Otras transacciones pueden crear procedimientos que hagan referencia a las mismas tablas y adquirir bloqueos DDL de uso compartido simultáneos en las mismas tablas, pero ninguna transacción puede adquirir un bloqueo DDL exclusivo en ninguna tabla a la que se haga referencia.

Un bloqueo DDL de recurso compartido dura la ejecución de la sentencia DDL y la confirmación automática. Por lo tanto, una transacción que contiene un bloqueo DDL de recurso compartido garantiza que la definición del objeto de esquema al que se hace referencia permanece constante durante la transacción.

Bloqueos de análisis divisibles

Un bloqueo de análisis está retenido por una sentencia SQL o una unidad de programa PL/SQL para cada objeto de esquema al que hace referencia.

Los bloqueos de análisis se adquieren para que el área SQL compartida asociado se pueda invalidar si se modifica o borra un objeto al que se hace referencia. Un bloqueo de análisis se denomina bloqueo de análisis interrumpible porque no desactiva ninguna operación de DDL y se puede interrumpir para permitir operaciones de DDL en conflicto.

Se adquiere un bloqueo de análisis en el pool compartido durante la fase de análisis de la ejecución de sentencias SQL. El bloqueo se mantiene siempre que el área SQL compartida para esa sentencia permanezca en el pool compartido.

Consulte también: "Agrupación compartida"

Bloqueos del sistema

Oracle AI Database utiliza varios tipos de bloqueos del sistema para proteger la base de datos interna y las estructuras de memoria. Estos mecanismos no son accesibles para los usuarios porque estos no tienen control sobre su ocurrencia o duración.

Bloqueos Internos

Un bloqueo es un mecanismo de serialización simple y de bajo nivel que coordina el acceso de varios usuarios a estructuras de datos, objetos y archivos compartidos.

Los bloqueos internos protegen los recursos de memoria compartida de la corrupción cuando se accede mediante varios procesos. En concreto, los bloqueos internos protegen las estructuras de datos de las siguientes situaciones:

Normalmente, un bloqueo interno único protege varios objetos en el SGA. Por ejemplo, los procesos en segundo plano, como DBW y LGWR, asignan memoria del pool compartido para crear estructuras de datos. Para asignar esta memoria, estos procesos utilizan un bloqueo interno del pool compartido que serializa el acceso para evitar que dos procesos intenten inspeccionar o modificar el pool compartido simultáneamente. Después de asignar la memoria, es posible que otros procesos necesiten acceder a áreas de pool compartido, como la caché de biblioteca, que es necesaria para el análisis. En este caso, procesa el bloqueo interno solo de la caché de biblioteca, no de todo el pool compartido.

A diferencia de los bloqueos internos en cola, como los bloqueos de fila, los bloqueos internos no permiten que las sesiones se coloquen en cola. Cuando un bloqueo interno pasa a estar disponible, la primera sesión que solicita el bloqueo interno obtiene acceso exclusivo a él. El fenómeno de giro interbloqueo se produce cuando un proceso solicita repetidamente un bloqueo interno en un bucle, mientras que giro interbloqueo interbloqueo se produce cuando un proceso libera la CPU antes de renovar la solicitud de bloqueo interno.

Normalmente, un proceso de Oracle adquiere un bloqueo interno durante un tiempo extremadamente corto mientras manipula o observa una estructura de datos. Por ejemplo, al procesar una actualización salarial de un solo empleado, la base de datos puede obtener y liberar miles de bloqueos internos. La implementación de bloqueos internos depende del sistema operativo, especialmente con respecto a si un proceso espera un bloqueo interno y cuánto tiempo.

Un aumento en el bloqueo interno significa una disminución de la simultaneidad. Por ejemplo, el exceso de operaciones de análisis pesado crea contención para el bloqueo interno de la caché de biblioteca. La vista V$LATCH contiene estadísticas detalladas de uso de bloqueo interno para cada bloqueo interno, incluido el número de veces que se solicitó y esperó cada bloqueo interno.

Consulte además:

Exclusiones Mutuas

Un objeto de exclusión mutua (mutex) es un mecanismo de bajo nivel que impide que un objeto en la memoria caduque o se corrompa cuando los procesos simultáneos acceden a él. Un mutex es similar a un bloqueo interno, pero mientras que un bloqueo interno normalmente protege un grupo de objetos, un mutex protege un solo objeto.

Los mutex ofrecen varias ventajas:

Bloqueos internos

Los bloqueos internos son mecanismos de nivel superior y más complejos que los bloqueos internos y los mutex, y sirven para diversos fines.

La base de datos utiliza los siguientes tipos de bloqueos internos:

Consulte también: "Caché de Diccionario de Datos"

Descripción general de bloqueos de datos manuales

Puede sustituir manualmente los mecanismos de bloqueo por defecto de Oracle AI Database.

Oracle AI Database realiza bloqueos automáticamente para garantizar la simultaneidad de los datos, la integridad de los datos y la consistencia de lectura a nivel de sentencia. Sin embargo, la sustitución del bloqueo por defecto resulta útil en situaciones como las siguientes:

Puede sustituir el bloqueo automático de Oracle AI Database en el nivel de sesión o transacción. En el nivel de sesión, una sesión puede definir el nivel de aislamiento de transacciones necesario con la sentencia ALTER SESSION. En el nivel de transacción, las transacciones que incluyen las siguientes sentencias SQL sustituyen el bloqueo por defecto de Oracle AI Database:

Los bloqueos adquiridos por las sentencias anteriores se liberan después de que finaliza la transacción o un rollback para liberar los puntos de grabación.

Si el bloqueo por defecto de Oracle AI Database se sustituye en cualquier nivel, el administrador de la base de datos o el desarrollador de la aplicación deben asegurarse de que los procedimientos de bloqueo de sustitución funcionan correctamente. Los procedimientos de bloqueo deben cumplir los siguientes criterios: se garantiza la integridad de los datos, se acepta la simultaneidad de los datos y no se pueden realizar interbloqueos o se gestionan correctamente.

Consulte además:

Visión General de Bloqueos Definidos por el Usuario

Con los servicios de gestión de bloqueo de Oracle AI Database, puede definir sus propios bloqueos para una aplicación específica.

Por ejemplo, puede crear un bloqueo para serializar el acceso a un registro de mensajes en el sistema de archivos. Dado que un bloqueo de usuario reservado es el mismo que un bloqueo de Oracle AI Database, tiene toda la funcionalidad de bloqueo de Oracle AI Database, incluida la detección de interbloqueos. Los bloqueos de usuario nunca entran en conflicto con los bloqueos de Oracle AI Database, porque se identifican con el prefijo UL.

Los servicios de gestión de bloqueo de Oracle AI Database están disponibles mediante los procedimientos del paquete DBMS_LOCK. Puede incluir sentencias en bloques PL/SQL que:

Consulte además:


Notas

Nota a Pie de Página 1:

Al procesar una confirmación distribuida en dos fases, la base de datos puede impedir brevemente el acceso de lectura en circunstancias especiales. En concreto, si una consulta se inicia entre las fases de preparación y confirmación e intenta leer los datos antes de la confirmación, la base de datos puede escalar un bloqueo de nivel de fila a nivel de bloque para garantizar la consistencia de lectura.