database - Mejores prácticas de transacciones
design architecture (8)
¡Guauu! ¡Muchas preguntas!
Hasta hace un año dependía 100% de las transacciones. Ahora es solo el 98%. En casos especiales de sitios web de alto tráfico (como mencionó Sara) y también datos altos de particiones, que imponen la necesidad de transacciones distribuidas, se puede adoptar una arquitectura sin transacciones. Ahora tendrá que codificar la integridad referencial en la aplicación.
Además, me gusta administrar las transacciones declarativamente usando anotaciones (soy un tipo Java) y aspectos. Esa es una forma muy clara de determinar los límites de las transacciones e incluye la funcionalidad de propagación de transacciones.
¿Cuánto confías en las transacciones de la base de datos?
¿Prefiere alcances de transacción pequeños o grandes?
¿Prefiere el manejo de transacciones del lado del cliente (por ejemplo, TransactionScope en .NET) sobre las transacciones del lado del servidor o viceversa?
¿Qué pasa con las transacciones anidadas?
¿Tiene algunos consejos y trucos relacionados con las transacciones?
¿Algún problema que haya encontrado al trabajar con una transacción?
Todo tipo de respuestas son bienvenidas.
Al igual que un FYI ... las transacciones anidadas pueden ser peligrosas. Simplemente aumenta las posibilidades de quedar estancado. Entonces, aunque es bueno y necesario, la forma en que se implementa es importante en situaciones de mayor volumen.
Como dijo Sara Chipps, la transacción es excesiva para aplicaciones de alto tráfico. Entonces deberíamos evitarlo tanto como sea posible. En otras palabras, usamos una arquitectura BASE en lugar de ACID. Ebay es un caso típico. La transacción distribuida no se usa en absoluto en la arquitectura de Ebay. Pero para una coherencia final , tienes que hacer algún tipo de truco por tu cuenta.
Este es un enlace interesante para anidar transacciones T-SQL: http://aleemkhan.wordpress.com/2006/07/21/t-sql-error-handling-pattern-for-nested-transactions-and-stored-procedures/
Personalmente, al desarrollar un sitio web basado en el alto rendimiento del tráfico, me mantengo alejado de las transacciones de la base de datos siempre que sea posible. Obviamente son necesarios, entonces uso un ORM y variables de objetos de nivel de página para minimizar el número de llamadas del lado del servidor que tengo que hacer.
Las transacciones anidadas son una excelente manera de minimizar sus llamadas, me dirijo en esa dirección siempre que puedo siempre y cuando sean consultas rápidas que no causen bloqueo. NHibernate ha sido un salvador en estos casos.
Siempre envuelvo una transacción en una declaración de uso.
using(IDbTransaction transaction )
{
// logic goes here.
transaction.Commit();
}
Una vez que la transacción se mueve fuera del alcance, se elimina. Si la transacción aún está activa, se revierte. Este comportamiento falla: le impide bloquear accidentalmente la base de datos. Incluso si se lanza una excepción no controlada, la transacción aún se revertirá.
En mi código, realmente omito retrocesos explícitos y confío en la declaración de uso para hacer el trabajo por mí. Solo realizo commits explícitamente.
Descubrí que este patrón ha reducido drásticamente los problemas de bloqueo de registros.
Transacciones del lado del servidor, 35,000 transacciones por segundo, SQL Server: 10 lecciones de 35K tps
Solo usamos transacciones del lado del servidor:
- puede comenzar más tarde y terminar antes
- no distribuido
- puede hacer el trabajo antes y después
- SET XACT_ABORT ON significa repliegue inmediato en caso de error
- cliente / OS / controlador agnóstico
Otro:
- anidamos llamadas pero usamos @@ TRANCOUNT para detectar TXN ya iniciadas
- cada llamada a DB siempre es atómica
Trabajamos con millones de filas INSERT por día (algunas agrupadas a través de tablas de etapas), OLTP completo, sin problemas. Sin embargo, no 35k tps.
Uso transacciones en cada operación de escritura en la base de datos.
Así que hay bastantes pequeñas "transacciones" envueltas en una transacción más grande y, básicamente, hay un recuento de transacciones pendientes en el código de anidación. Si hay hijos pendientes al finalizar el padre, todo se revierte.
Prefiero el manejo de transacciones del lado del cliente donde esté disponible. Si está relegado a hacer sps u otras unidades de trabajo lógicas del lado del servidor, las transacciones del lado del servidor están bien.