2008-11-21 8 views
22

He estado leyendo que algunos desarrolladores/dbas recomiendan usar transacciones en todas las llamadas a bases de datos, incluso llamadas de solo lectura. Si bien entiendo cómo insertar/actualizar dentro de una transacción, ¿cuál es el beneficio de leer dentro de una transacción?¿Debería haber una transacción para consultas leídas?

Respuesta

26

Para obtener una vista coherente de la base de datos. Imagine que tiene dos tablas que enlazan entre sí, pero por alguna razón usted selecciona 2 ... en pseuodocode:

myRows = query(SELECT * FROM A) 
moreRows = query(SELECT * FROM B WHERE a_id IN myRows[id]) 

Si entre las dos consultas, alguien cambia B para borrar algunas filas, vas tener un problema

+0

Este no es siempre el caso. La implementación del lado del cliente puede tomar una instantánea completa de la tabla y mostrar los resultados esperados. ADO.NET permite consultas sin conexión. – Kieveli

+5

En realidad, depende de algunas cosas, incluida la configuración de su servidor. La pregunta fue por qué pondría un SELECT dentro de una transacción ... esa es la razón por la cual. – Greg

+0

+1 esta explicación muy clara. Sí, depende de otras cosas (cuando se usa Hibernate o NHibernate, por ejemplo, los objetos se guardan en caché después de leerlos), pero el aislamiento es uno de los cuatro principios de las transacciones y no debe olvidarse. –

0

Diría que uno de los propósitos principales de una transacción es ofrecer un potencial de reversión si hay algún problema, que no se cumple cuando simplemente se lee.

1

He encontrado que las 'transacciones' se comportan de manera muy diferente en diferentes servidores SQL. En algunos casos, iniciar una transacción bloquea todas las demás conexiones para que no puedan ejecutar ningún SQL hasta que la transacción se confirme o se retrotraiga (MS SQLServer 6.5). Otros no tienen ningún problema, y ​​solo se bloquean cuando hay una modificación (oráculo). Los bloqueos incluso pueden expandirse para abarcar solo sus cambios: bloqueos de celda/bloqueos de fila/bloqueos de página/bloqueos de tabla.

Normalmente utilizo las transacciones solo cuando se debe mantener la integridad de los datos entre varias instrucciones de inserción/eliminación/actualización. Aún así, prefiero implementar esto utilizando eliminaciones en cascada definidas por la BD para que la base de datos lo haga automática y atómicamente.

Utilice una transacción si puede prever una situación en la que le gustaría deshacer varias modificaciones, pero de lo contrario, la base de datos hará sus actualizaciones atómicas sin el código adicional para manejarlo.

1

He estado revisando esto en los últimos minutos, ya que es algo que debería saber más. Esto es lo que he encontrado.

Las transacciones serían útiles en una selección si desea bloquear esa fila mientras una persona está leyendo registros y no quiere que se modifique o lea. Por ejemplo ejecutar estas consultas:

(en ventana de consulta 1)

COMENZAR TRAN SELECT * FROM MYTABLE CON (ROWLOCK XLOCK) donde ID = 1

(en ventana de consulta 2)

SELECT * FROM MITABLA donde id = 1

(consulta ventana 2 no proporcione resultados hasta que se ejecute esta en la ventana 1)

COMMIT TRAN

Enlaces de interés:

http://msdn.microsoft.com/en-us/library/aa213039.aspx

http://msdn.microsoft.com/en-us/library/aa213026.aspx

http://msdn.microsoft.com/en-us/library/ms190345.aspx

Mi objetivo era conseguir algo para bloquear el - y finalmente funcionó después de añadir el XLOCK allí . Simplemente usar ROWLOCK no funcionaba.Supongo que estaba emitiendo un bloqueo compartido (y los datos habían sido leídos) ... pero todavía estoy explorando esto.

Agregar - WITH (UPDLOCK ROWLOCK) - le permitirá seleccionar y bloquear las filas para las actualizaciones, lo que ayudaría con la simultaneidad.

Tenga cuidado con los consejos de la tabla. Si comienza a aplicarlos al azar, su sistema se ralentizará si obtiene incluso un pequeño número de usuarios en su aplicación. Esa es la única cosa que sabía antes de investigar esto;)

3

Similar a lo que dijo RoBorg, usted haría SELECCIONES con transacciones i/i para evitar la lectura de datos fantasmas entre las declaraciones. PERO es importante tener en cuenta que el nivel de aislamiento de transacción predeterminado en SQL Server es LEÍDO COMPROMETIDO, lo que solo evitará lecturas sucias; para evitar los datos fantasma tendrías que usar al menos REPEATABLE READ. "Use esta opción solo cuando sea necesario".

http://msdn.microsoft.com/en-us/library/ms173763.aspx

Cuestiones relacionadas