Pregunta

Teniendo en cuenta una mesa foro y muchos usuarios al mismo tiempo la inserción de mensajes en él, qué tan seguro es esta transacción?

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION

 DECLARE @LastMessageId SMALLINT
 SELECT @LastMessageId = MAX(MessageId)
 FROM Discussions
 WHERE ForumId = @ForumId AND DiscussionId = @DiscussionId

 INSERT INTO Discussions
 (ForumId, DiscussionId, MessageId, ParentId, MessageSubject, MessageBody)
 VALUES
 (@ForumId, @DiscussionId, @LastMessageId + 1, @ParentId, @MessageSubject, @MessageBody)

IF @@ERROR = 0
BEGIN
 COMMIT TRANSACTION
 RETURN 0
END

ROLLBACK TRANSACTION
RETURN 1

Aquí leí última MessageId y se incrementará. No puedo utilizar el campo de identidad ya que tiene que ser incrementado por cada mensaje se inserta en un grupo (no todos los mensajes de inserción en la tabla.)

¿Fue útil?

Solución

La transacción debe ser bastante segura de hecho - echa un vistazo a los documentos MSDN en el SERIALIZABLE nivel de transacción :

SERIALIZABLE

especifica lo siguiente:

  • Declaraciones no pueden leer los datos que han sido modificados , pero aún no cometido por otras transacciones.

  • No hay otras transacciones pueden modificar los datos que ha sido leído por el transacción actual hasta que la corriente la transacción termine.

  • Otras operaciones no puede insertar nuevas filas con valores clave que caería en el rango de teclas leer por cualquier declaración en el actual transacción hasta que la corriente la transacción termine.

bloqueos de intervalo se sitúan en el rango de los valores clave que coinciden con el condiciones de cada sentencia de búsqueda ejecutado en una transacción. esto bloquea otras operaciones de actualización o la inserción de las filas que se califica para cualquiera de las declaraciones realizadas por la transacción actual. Esto significa que si alguna de las declaraciones en una transacción se ejecuta una segunda tiempo, que van a leer el mismo conjunto de filas. Los bloqueos de intervalo se mantienen hasta se complete la transacción. Este es el más restrictivo del aislamiento los niveles, ya que entrelaza rangos enteros de llaves y mantiene los bloqueos hasta que el la transacción termine. Porque concurrencia es menor, utilice esta opción Solo cuando sea necesario. Esta opción tiene el mismo efecto que establecer en HOLDLOCK todas las tablas de todas las instrucciones SELECT en una transacción.

El problema principal con este nivel de aislamiento es que es una carga pesada bastante en el servidor, y serializa (como su nombre indica) cualquier acceso, por lo que su rendimiento del servidor y la escalabilidad van a sufrir, por ejemplo, con un número muy elevado de usuarios, que posiblemente va a obtener una gran cantidad de tiempos de espera para los usuarios que esperan para una transacción a fin.

Así, utilizando el enfoque más ligero de un mensaje de identificación global como INT IDENTITY es definitivamente mucho mejor!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top