{"meta":{"title":"Corrección de los interbloqueos de base de datos o los problemas de integridad de datos","intro":"Copilot Chat puede ayudarle a evitar código que provoque operaciones de base de datos lentas o bloqueadas, o tablas con datos que faltan o son incorrectos.","product":"GitHub Copilot","breadcrumbs":[{"href":"/es/enterprise-cloud@latest/copilot","title":"GitHub Copilot"},{"href":"/es/enterprise-cloud@latest/copilot/tutorials","title":"Tutoriales"},{"href":"/es/enterprise-cloud@latest/copilot/tutorials/copilot-cookbook","title":"Recetario de GitHub Copilot"},{"href":"/es/enterprise-cloud@latest/copilot/tutorials/copilot-cookbook/refactor-code","title":"Refactorización de código"},{"href":"/es/enterprise-cloud@latest/copilot/tutorials/copilot-cookbook/refactor-code/fix-database-deadlocks","title":"Corrección de los interbloqueos de base de datos"}],"documentType":"article"},"body":"# Corrección de los interbloqueos de base de datos o los problemas de integridad de datos\n\nCopilot Chat puede ayudarle a evitar código que provoque operaciones de base de datos lentas o bloqueadas, o tablas con datos que faltan o son incorrectos.\n\nLas operaciones complejas de base de datos, especialmente en las que intervienen transacciones, pueden provocar interbloqueos o incoherencias de datos difíciles de depurar.\n\nCopilot Chat puede ayudar mediante la identificación de puntos en una transacción en la que se pueden producir bloqueos o interbloqueos, y puede sugerir procedimientos recomendados para el aislamiento de transacciones o la resolución de interbloqueos, como ajustar estrategias de bloqueo o controlar las excepciones de interbloqueo correctamente.\n\n> \\[!NOTE] Las respuestas que se muestran en este artículo son ejemplos.\n> Copilot Chat las respuestas son no deterministas, por lo que puede obtener respuestas diferentes de las que se muestran aquí.\n\n## Evitar actualizaciones simultáneas en filas interdependientes\n\nCuando dos o más transacciones intentan actualizar las mismas filas de una tabla de base de datos, pero en distinto orden, se puede producir una condición de espera circular.\n\n### Escenario de ejemplo\n\nEl siguiente fragmento de código SQL actualiza una fila de una tabla y, a continuación, realiza una operación que tarda varios segundos para posteriormente actualizar otra fila de la misma tabla. Esto es problemático porque la transacción bloquea la fila `id = 1` durante varios segundos antes de que finalice la transacción, liberando el bloqueo. Si otra transacción que realiza una operación similar se inicia durante este tiempo, pero bloquea primero la fila `id = 2` para poder actualizarla y luego intenta bloquear la fila `id = 1`, ambas transacciones se quedarán esperando a que se complete la otra, lo que dará lugar a un interbloqueo.\n\n```sql id=deadlock-example\nBEGIN TRANSACTION;\nUPDATE my_table SET value = 'Some value' WHERE id = 301;\n-- Simulate a process taking 5 seconds:\nWAITFOR DELAY '00:00:05';\nUPDATE my_table SET value = 'Another value' WHERE id = 127;\nCOMMIT TRANSACTION;\n```\n\n### Ejemplo de solicitud 1\n\nPuedes comprobar si hay algún problema con esta transacción.\n\nEn el editor, seleccione el código de transacción y, a continuación, pregunte a Copilot Chat:\n\n```copilot copy prompt ref=deadlock-example\nIs this transaction good?\n```\n\n### Respuesta de ejemplo 1\n\nCopilot indica que \"la transacción en el código SQL es generalmente correcta\", pero enumera algunas cosas que puede considerar: duración del bloqueo, control de errores y simultaneidad. Menciona que \"la transacción contiene bloqueos durante un período prolongado, lo que podría provocar obstrucciones o interbloqueos\". La respuesta también incluye código revisado que agrega control de errores.\n\nEn este caso, decides no agregar el control de errores. Ahora mismo desea abordar la posibilidad de que aparezcan bloqueos.\n\n### Ejemplo de mensaje 2\n\nEscribe esta indicación de seguimiento:\n\n```copilot copy prompt ref=deadlock-example\nHow can I rewrite this code to reduce the chance of deadlock to a minimum while not adversely affecting performance. Tell me anything else I can do to avoid a deadlock. Note: I don't want to add error handling at this time.\n```\n\n### Respuesta de ejemplo 2\n\nCopilot proporciona los siguientes consejos:\n\n> *\n\n**Orden de Acceso:** Asegúrese de que todas las transacciones accedan a tablas y filas en el mismo orden.\n\n> \\*\n> **Procurar que las transacciones sean cortas:** minimiza el tiempo que una transacción contiene bloqueos.\n> \\*\n> **Usar los niveles de aislamiento adecuados:** usa el nivel de aislamiento más bajo que cumpla tus requisitos.\n>\n> Esta es una versión revisada del código:\n\n```sql\nBEGIN TRANSACTION;\n-- Update the rows in a consistent order\nUPDATE my_table SET value = 'Another value' WHERE id = 127;\nUPDATE my_table SET value = 'Some value' WHERE id = 301;\n-- Simulate a process taking 5 seconds:\nWAITFOR DELAY '00:00:05';\nCOMMIT TRANSACTION;\n```\n\n## Evitar búsquedas no indexadas\n\nLa búsqueda en columnas de tabla que no se han indexado normalmente dará lugar a un escaneo de la tabla completo. Este proceso puede ser muy lento y consumir muchos recursos, lo que aumenta la probabilidad de cuellos de botella en el rendimiento.\n\n### Escenario de ejemplo\n\nEl siguiente código SQL dará como resultado un escaneo de tabla completo si `some_column` no está indexado:\n\n```sql id=full-table-scan\nBEGIN TRANSACTION;\nSELECT * FROM my_table WHERE some_column = 'some_value';\n-- More actions here, then:\nCOMMIT TRANSACTION;\n```\n\n### Mensaje de ejemplo\n\nLa pregunta Copilot siguiente suele revelar el posible problema.\n\n```copilot copy prompt ref=full-table-scan\nHow can I optimize this transaction?\n```\n\n### Respuesta de ejemplo\n\nCopilot proporciona algunos consejos y menciona que la columna debe indexarse:\n\n> Para optimizar la transacción, debes asegurarte de que la transacción sea lo más corta posible para reducir el bloqueo y mejorar el rendimiento. Estas son algunas sugerencias:\n>\n> 1.\n\n**Minimizar el trabajo realizado en la transacción:** incluye solamente las operaciones necesarias dentro de la transacción.\n\n> 1\\.\n> **Usar índices adecuados:** asegúrate de que las columnas usadas en la cláusula WHERE estén indexadas.\n> 1\\.\n> **Evitar transacciones de larga duración:** la duración de la transacción debe ser corta para evitar problemas de bloqueo.\n\nEl código sugerido en la respuesta incluye el comando SQL para indexar la columna:\n\n```sql\n`CREATE INDEX idx_some_column ON my_table(some_column);`\n```\n\n## Evitar transacciones de larga duración\n\nEs importante evitar consultas y transacciones de larga duración, siempre que sea posible, ya que pueden degradar gravemente el rendimiento y provocar cuellos de botella en otras operaciones. Además, pueden consumir memoria y espacio de registro considerables, lo que hace que la aplicación sea más propensa a errores en entornos de carga elevada.\n\n### Escenario de ejemplo\n\nEl siguiente código SQL crea nuevas filas en `target_table`, que contienen datos de campos seleccionados de filas en `source_table` donde se cumplen varias condiciones. Si `source_table` es extremadamente grande, se puede producir una transacción de larga duración.\n\n```sql id=long-running-transaction\nBEGIN TRANSACTION;\n\nINSERT INTO target_table (first_name, last_name, email, dept, role, hire_date)\nSELECT first_name, last_name, email, department, job_title, start_date\nFROM source_table\nWHERE (department = 'Engineering' AND (salary > 95000 OR grade > 5))\n  OR (department = 'Marketing' AND performance_rating = 'Excellent');\n\nCOMMIT;\n```\n\n### Mensaje de ejemplo\n\nPuede preguntar Copilot si es posible evitar transacciones de larga duración.\n\n```copilot copy prompt ref=long-running-transaction\nsource_table is an extremely large table. Without altering the table, how can I ensure this SQL doesn't become a long-running query, that blocks other operations?\n```\n\n### Respuesta de ejemplo\n\nCopilot sugiere las estrategias siguientes:\n\n* **Procesamiento por lotes:** procesa los datos en lotes más pequeños en lugar de una sola transacción de gran tamaño. Esto se puede hacer usando un bucle con un límite y un desplazamiento.\n* **Indexación:** asegúrate de que las columnas usadas en la cláusula `WHERE` (`department`, `salary`, `grade`y `performance_rating`) se indexan para acelerar la consulta.\n* **Bloqueo:** Utilice el bloqueo de nivel de fila para evitar el bloqueo de toda la tabla.\n\nProporciona el ejemplo siguiente de cómo puedes implementar el procesamiento por lotes. Este código SQL procesa los datos en lotes de 1000 filas a la vez, lo que reduce la carga en la base de datos y evita las transacciones de larga duración.\n\n```sql\nDECLARE @BatchSize INT = 1000;\nDECLARE @Offset INT = 0;\nDECLARE @RowCount INT;\n\nSET @RowCount = @BatchSize;\n\nWHILE @RowCount = @BatchSize\nBEGIN\n    BEGIN TRANSACTION;\n\n    INSERT INTO target_table (first_name, last_name, email, dept, role, hire_date)\n    SELECT first_name, last_name, email, department, job_title, start_date\n    FROM source_table\n    WHERE (department = 'Engineering' AND salary > 95000)\n       OR (department = 'Engineering' AND years_of_experience > 5)\n       OR (department = 'Marketing' AND performance_rating = 'Excellent');\n    ORDER BY primary_key_column\n    OFFSET @Offset ROWS FETCH NEXT @BatchSize ROWS ONLY;\n\n    SET @RowCount = @@ROWCOUNT;\n    SET @Offset = @Offset + @BatchSize;\n\n    COMMIT;\nEND;\n```\n\nCopilot le indica que sustituya `primary_key_column` en el código sugerido por el nombre de la columna de la clave primaria real de `source_table`.\n\n## Evitar problemas de integridad de los datos\n\nEs importante que la información de las bases de datos siga siendo exacta, coherente y completa. Las consultas mal diseñadas pueden dar lugar a datos que faltan o son incorrectos.\n\n### Escenario de ejemplo\n\nLa siguiente transacción SQL elimina un registro de empleado y crea un registro de eliminación. Sin embargo, es posible que la operación `DELETE` se realice correctamente y que la operación `INSERT` genere un error, en cuyo caso no hay ningún registro para la eliminación.\n\n```sql id=delete-employee\nBEGIN TRANSACTION;\n\nDELETE FROM employees\nWHERE employee_id = 101;\n\nINSERT INTO deletion_log (employee_id, deletion_date, reason)\nVALUES (101, GETDATE(), 'Voluntary Resignation');\n\nCOMMIT TRANSACTION;\n```\n\n### Mensaje de ejemplo\n\n```copilot copy prompt ref=delete-employee\nHow can I ensure that the DELETE and INSERT operations are only performed if both succeed?\n```\n\n### Respuesta de ejemplo\n\nCopilot le indica que lo logra mediante una transacción con control de errores. Proporciona el ejemplo siguiente usando la construcción `TRY...CATCH` de SQL Server:\n\n```sql\nBEGIN TRY\n    BEGIN TRANSACTION;\n\n    DELETE FROM employees\n    WHERE employee_id = 101;\n\n    INSERT INTO deletion_log (employee_id, deletion_date, reason)\n    VALUES (101, GETDATE(), 'Voluntary Resignation');\n\n    COMMIT TRANSACTION;\nEND TRY\nBEGIN CATCH\n    ROLLBACK TRANSACTION;\n    -- Handle the error, e.g., log it or re-throw\n    DECLARE @ErrorMessage NVARCHAR(4000);\n    DECLARE @ErrorSeverity INT;\n    DECLARE @ErrorState INT;\n\n    SELECT\n        @ErrorMessage = ERROR_MESSAGE(),\n        @ErrorSeverity = ERROR_SEVERITY(),\n        @ErrorState = ERROR_STATE();\n\n    RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);\nEND CATCH;\n```\n\nEl código sugerido garantiza que, si se produce un error en la operación `DELETE` o `INSERT`, la transacción se revierte y no se realizan cambios en la base de datos.\n\n## Lectura adicional\n\n* [Ingeniería de mensajes para GitHub Copilot Chat](/es/enterprise-cloud@latest/copilot/concepts/prompting/prompt-engineering)\n* [Procedimientos recomendados para usar GitHub Copilot](/es/enterprise-cloud@latest/copilot/get-started/best-practices)"}