Uso de transacciones en un grupo de SQL en Azure Synapse
En este artículo se incluyen sugerencias para implementar transacciones y desarrollar soluciones en un grupo de SQL.
Qué esperar
Como cabría esperar, el grupo de SQL admite transacciones como parte de la carga de trabajo de almacenamiento de datos. Sin embargo, para asegurarse de que el grupo de SQL se mantiene a escala, algunas características están limitadas en comparación con SQL Server. En este artículo se resaltan las diferencias.
Niveles de aislamiento de transacciones
El grupo de SQL implementa transacciones ACID. El nivel de aislamiento de la compatibilidad transaccional se establece de forma predeterminada en READ UNCOMMITTED. Para cambiarlo a READ COMMITTED SNAPSHOT ISOLATION, active la opción de base de datos READ_COMMITTED_SNAPSHOT de un grupo de SQL de usuario cuando se conecte a la base de datos maestra.
Una vez habilitada, todas las transacciones de esta base de datos se ejecutan en READ COMMITTED SNAPSHOT ISOLATION y no se respeta la opción de configuración READ UNCOMMITTED en el nivel de sesión. Consulte Opciones de ALTER DATABASE SET (Transact-SQL) para obtener más información.
Tamaño de la transacción
Una transacción de modificación de datos única tiene un tamaño limitado. El límite se aplica por distribución. Por lo tanto, la asignación total puede calcularse multiplicando el límite por el recuento de distribución.
Para aproximar el número máximo de filas de la transacción, divida el extremo de la distribución entre el tamaño total de cada fila. Para las columnas de longitud variable, plantéese utilizar la longitud media de la columna en lugar del tamaño máximo.
En la tabla siguiente se han realizado dos supuestos:
- Se ha producido una distribución uniforme de los datos
- La longitud media de la fila es de 250 bytes
Gen2
DWU | Extremo por distribución (GB) | Número de distribuciones | Tamaño de la transacción MAX (GB) | N-º de filas por distribución | Máximo de filas por transacción |
---|---|---|---|---|---|
DW100c | 1 | 60 | 60 | 4 000 000 | 240 000 000 |
DW200c | 1.5 | 60 | 90 | 6\.000.000 | 360 000 000 |
DW300c | 2.25 | 60 | 135 | 9 000 000 | 540 000 000 |
DW400c | 3 | 60 | 180 | 12 000 000 | 720 000 000 |
DW500c | 3,75 | 60 | 225 | 15 000 000 | 900 000 000 |
DW1000c | 7.5 | 60 | 450 | 30 000 000 | 1 800 000 000 |
DW1500c | 11,25 | 60 | 675 | 45 000 000 | 2 700 000 000 |
DW2000c | 15 | 60 | 900 | 60 000 000 | 3 600 000 000 |
DW2500c | 18,75 | 60 | 1125 | 75 000 000 | 4 500 000 000 |
DW3000c | 22.5 | 60 | 1,350 | 90,000,000 | 5,400,000,000 |
DW5000c | 37.5 | 60 | 2250 | 150 000 000 | 9 000 000 000 |
DW6000c | 45 | 60 | 2,700 | 180,000,000 | 10,800,000,000 |
DW7500c | 56,25 | 60 | 3375 | 225 000 000 | 13 500 000 000 |
DW10000c | 75 | 60 | 4500 | 300.000.000 | 18 000 000 000 |
DW15000c | 112,5 | 60 | 6750 | 450 000 000 | 27 000 000 000 |
DW30000c | 225 | 60 | 13 500 | 900 000 000 | 54 000 000 000 |
Gen1
DWU | Extremo por distribución (GB) | Número de distribuciones | Tamaño de la transacción MAX (GB) | N-º de filas por distribución | Máximo de filas por transacción |
---|---|---|---|---|---|
DW100 | 1 | 60 | 60 | 4 000 000 | 240 000 000 |
DW200 | 1.5 | 60 | 90 | 6\.000.000 | 360 000 000 |
DW300 | 2.25 | 60 | 135 | 9 000 000 | 540 000 000 |
DW400 | 3 | 60 | 180 | 12 000 000 | 720 000 000 |
DW500 | 3,75 | 60 | 225 | 15 000 000 | 900 000 000 |
DW600 | 4.5. | 60 | 270 | 18 000 000 | 1 080 000 000 |
DW1000 | 7.5 | 60 | 450 | 30 000 000 | 1 800 000 000 |
DW1200 | 9 | 60 | 540 | 36 000 000 | 2 160 000 000 |
DW1500 | 11,25 | 60 | 675 | 45 000 000 | 2 700 000 000 |
DW2000 | 15 | 60 | 900 | 60 000 000 | 3 600 000 000 |
DW3000 | 22.5 | 60 | 1,350 | 90,000,000 | 5,400,000,000 |
DW6000 | 45 | 60 | 2,700 | 180,000,000 | 10,800,000,000 |
Se aplica el límite de tamaño de la transacción por transacción u operación. No se aplica en todas las transacciones simultáneas. Por tanto, cada transacción puede escribir esta cantidad de datos en el registro.
Para optimizar y minimizar la cantidad de datos que se escriben en el registro, consulte el artículo Procedimientos recomendados relacionados con las transacciones.
Advertencia
El tamaño máximo de la transacción solo se puede conseguir para las tablas de distribución HASH o ROUND_ROBIN donde la propagación de los datos es uniforme. Si la transacción está escribiendo datos de forma sesgada en las distribuciones, es posible que el límite se alcance antes de que la transacción llegue al máximo de su tamaño.
Estado de las transacciones
El grupo de SQL usa la función XACT_STATE() para notificar una transacción errónea con el valor -2. Este valor indica que la transacción no se ha realizado y que solo se marca para reversión.
Nota
El uso de -2 por la función XACT_STATE para denotar una transacción errónea representa un comportamiento diferente para SQL Server. SQL Server utiliza el valor -1 para representar una transacción no confirmable. SQL Server puede tolerar algunos errores en una transacción sin necesidad de que se marque como no confirmable. Por ejemplo, SELECT 1/0
produciría un error, pero no forzaría una transacción a un estado no confirmable.
SQL Server también permite lecturas en la transacción no confirmable. Sin embargo, el grupo de SQL no permite hacer esto. Si se produce un error dentro de una transacción del grupo de SQL, especificará automáticamente el estado -2 y no podrá realizar más instrucciones select hasta que la instrucción se haya revertido.
Como tal, es importante comprobar el código de aplicación para ver si utiliza XACT_STATE() cuando necesite realizar modificaciones del código.
Por ejemplo, puede que vea una transacción con el siguiente aspecto en SQL Server:
SET NOCOUNT ON;
DECLARE @xact_state smallint = 0;
BEGIN TRAN
BEGIN TRY
DECLARE @i INT;
SET @i = CONVERT(INT,'ABC');
END TRY
BEGIN CATCH
SET @xact_state = XACT_STATE();
SELECT ERROR_NUMBER() AS ErrNumber
, ERROR_SEVERITY() AS ErrSeverity
, ERROR_STATE() AS ErrState
, ERROR_PROCEDURE() AS ErrProcedure
, ERROR_MESSAGE() AS ErrMessage
;
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRAN;
PRINT 'ROLLBACK';
END
END CATCH;
IF @@TRANCOUNT >0
BEGIN
PRINT 'COMMIT';
COMMIT TRAN;
END
SELECT @xact_state AS TransactionState;
El código anterior muestra el siguiente mensaje de error:
Msg 111233, Level 16, State 1, Line 1 111233; La transacción actual se ha anulado y los cambios pendientes se han revertido. La causa de este problema es que una transacción en estado de solo reversión no se revierte explícitamente antes de una instrucción DDL, DML o SELECT.
Tampoco obtendrá el resultado de las funciones ERROR_*.
En el grupo de SQL, el código debe modificarse ligeramente:
SET NOCOUNT ON;
DECLARE @xact_state smallint = 0;
BEGIN TRAN
BEGIN TRY
DECLARE @i INT;
SET @i = CONVERT(INT,'ABC');
END TRY
BEGIN CATCH
SET @xact_state = XACT_STATE();
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRAN;
PRINT 'ROLLBACK';
END
SELECT ERROR_NUMBER() AS ErrNumber
, ERROR_SEVERITY() AS ErrSeverity
, ERROR_STATE() AS ErrState
, ERROR_PROCEDURE() AS ErrProcedure
, ERROR_MESSAGE() AS ErrMessage
;
END CATCH;
IF @@TRANCOUNT >0
BEGIN
PRINT 'COMMIT';
COMMIT TRAN;
END
SELECT @xact_state AS TransactionState;
Ahora se observa el comportamiento esperado. Se administra el error en la transacción y las funciones ERROR_* proporcionan los valores esperados.
Lo único que ha cambiado es que la operación ROLLBACK de la transacción tenía que producirse antes de la lectura de la información de error en el bloque CATCH.
Función Error_Line()
También cabe destacar que el grupo de SQL no implementa o admite la función ERROR_LINE(). Si ha incluido esta función en el código, tendrá que quitarla para que sea compatible con el grupo de SQL.
En su lugar, utilice etiquetas de consulta en el código para implementar una funcionalidad equivalente. Para obtener más información, vea el artículo sobre etiquetas.
Uso de THROW y RAISERROR
THROW es la implementación más moderna para producir excepciones en el grupo de SQL, pero también se admite RAISERROR. Sin embargo, hay algunas diferencias a las que se debe prestar atención.
- Los números de mensajes de error definidos por el usuario no pueden encontrarse en el intervalo de 100 000 a 150 000 para THROW.
- Los mensajes de error RAISERROR se fijan en 50.000.
- No se admite el uso de sys.messages.
Limitaciones
El grupo de SQL tiene algunas otras restricciones relacionadas con las transacciones.
Los pasos son los siguientes:
- Transacciones no distribuidas
- Transacciones anidadas no permitidas
- Puntos de almacenamiento no admitidos
- Sin transacciones con nombre
- Sin transacciones marcadas
- No existe compatibilidad con DDL como el elemento CREATE TABLE de una transacción definida por el usuario
Pasos siguientes
Para obtener más información sobre la optimización de transacciones, vea Procedimientos recomendados relacionados con las transacciones. Para más información sobre otros procedimientos recomendados del grupo de SQL, consulte Procedimientos recomendados del grupo de SQL.