locked
Transacciones paralelas SQL Server RRS feed

  • Pregunta

  • Hola a todos,

    Estoy desarrollando una aplicación con conexión a SQL Server y trabajo con threads y con conexiones independientes para cada uno de los hilos. Quiero realizar transacciones de forma paralela por varios hilos al mismo tiempo. Estoy utilizando SqlTransaction con IsolationLevel ReadUncommitted. Aún así no consigo que las transacciones funcionen de forma paralela. Hasta que no finaliza una no empieza la siguiente. ¿Cómo puedo conseguir esto?

    Gracias de antemano y un saludo. 

    viernes, 13 de marzo de 2015 10:20

Respuestas

  • - ¿Cuál sería el nivel de aislamiento más reducido o menos exigente?

    - ¿Cómo puedo activar la modalidad de aislamiento por instantáneas?

    El aislamiento menos exigente es el Read Uncommitted. Por lo que veo en tu pregunta original ya lo estás usando, así que no deberías tener problemas de bloqueos por las modificaciones de registros dentro de la transacción, siempre que no tengas por algún otro sitio otras transacciones que tengan un aislamiento mayor.

    El aislamiento por instantáneas se activa modificando la base de datos con estas sentencias:

    ALTER DATABASE MiBase SET ALLOW_SNAPSHOT_ISOLATION ON
    ALTER DATABASE MiBase SET READ_COMMITTED_SNAPSHOT ON

    Después de eso, cuando abras una transacción con el nivel de aislamiento Read Committed, te aplicará el aislamiento por instantáneas. Pero no lo apliques a ciegas, lee primero la documentación para cerciorarte de que su comportamiento es acorde con tus necesidades.

    Si ya con el ReadUncommitted te está fallando, no creo que el SnapshotIsolation te resuelva nada. Podrías usar el SQL Profiler junto con el perfil de captura de bloqueos para capturar la actividad del servidor SQL y observar el comportamiento de los bloqueos, a ver qué sentencia está loqueando a cuál y en qué orden las generan los threads del programa cliente. Esto te debería dar una pista acerca de por qué no funcionan en paralelo las transacciones de tu programa.

    También deberías "instrumentar" el programa cliente escribiendo sentencias del tipo "Debug.Write..." para ir haciendo el seguimiento de cuando entra y sale en cada transación y por qué partes del código pasa. Esto también te puede dar alguna pista acerca de dónde se está quedando bloqueado, para avanzar en la solución del problema.

    No te desanimes si lo encuentras complicado de resolver. La programación en multihilo es de las cosas más difíciles de hacer funcionar correctamente, sobre todo cuando los hilos manejan recursos comunes (tales como el servidor SQL).

    viernes, 13 de marzo de 2015 16:31

Todas las respuestas

  • En principio, sí que es lícito que hagas varias transacciones en paralelo, y todas funcionarán a la vez. PERO si dentro de una transacción modificas determinado objeto de la base de datos (tal como una fila de una tabla), se colocan bloqueos sobre ese objeto hasta que la transacción termina (con un commit o un rollback). Si mientras tanto otra transacción intenta acceder al mismo objeto, se queda parada esperando que la primera quite el bloqueo. Seguramente por eso tus transacciones aparentan no ejecutarse a la vez, porque todas deben estar tratando de acceder a un mismo objeto. Puedes aliviar el problema reduciendo el nivel de aislamiento de las transacciones (pero eso puede hacer que leas datos no confirmados aún), o activando la modalidad de aislamiento por instantáneas. Ninguna de estas decisiones es trivial, debes asegurarte de estudiar la documentación de SQL Server para comprender bien el impacto y consecuencias que tiene uno de estos cambios.
    viernes, 13 de marzo de 2015 10:30
  • Gracias por la rápida respuesta Alberto,

    Puedes explicarme un poco más como puedo realizar estas dos soluciones?

    - ¿Cuál sería el nivel de aislamiento más reducido o menos exigente?

    - ¿Cómo puedo activar la modalidad de aislamiento por instantáneas?

    Gracias de nuevo y un saludo,

    viernes, 13 de marzo de 2015 10:42
  • - ¿Cuál sería el nivel de aislamiento más reducido o menos exigente?

    - ¿Cómo puedo activar la modalidad de aislamiento por instantáneas?

    El aislamiento menos exigente es el Read Uncommitted. Por lo que veo en tu pregunta original ya lo estás usando, así que no deberías tener problemas de bloqueos por las modificaciones de registros dentro de la transacción, siempre que no tengas por algún otro sitio otras transacciones que tengan un aislamiento mayor.

    El aislamiento por instantáneas se activa modificando la base de datos con estas sentencias:

    ALTER DATABASE MiBase SET ALLOW_SNAPSHOT_ISOLATION ON
    ALTER DATABASE MiBase SET READ_COMMITTED_SNAPSHOT ON

    Después de eso, cuando abras una transacción con el nivel de aislamiento Read Committed, te aplicará el aislamiento por instantáneas. Pero no lo apliques a ciegas, lee primero la documentación para cerciorarte de que su comportamiento es acorde con tus necesidades.

    Si ya con el ReadUncommitted te está fallando, no creo que el SnapshotIsolation te resuelva nada. Podrías usar el SQL Profiler junto con el perfil de captura de bloqueos para capturar la actividad del servidor SQL y observar el comportamiento de los bloqueos, a ver qué sentencia está loqueando a cuál y en qué orden las generan los threads del programa cliente. Esto te debería dar una pista acerca de por qué no funcionan en paralelo las transacciones de tu programa.

    También deberías "instrumentar" el programa cliente escribiendo sentencias del tipo "Debug.Write..." para ir haciendo el seguimiento de cuando entra y sale en cada transación y por qué partes del código pasa. Esto también te puede dar alguna pista acerca de dónde se está quedando bloqueado, para avanzar en la solución del problema.

    No te desanimes si lo encuentras complicado de resolver. La programación en multihilo es de las cosas más difíciles de hacer funcionar correctamente, sobre todo cuando los hilos manejan recursos comunes (tales como el servidor SQL).

    viernes, 13 de marzo de 2015 16:31