Este artículo es un artículo espejo de traducción automática, por favor haga clic aquí para saltar al artículo original.

Vista: 42676|Respuesta: 4

[Fuente] Gestión de la distinción concurrente entre Timestamp y Concurrency Check

[Copiar enlace]
Publicado en 8/4/2017 0:10:50 | | | |


Autorwww.itsvse.com @小渣渣 !
¡Inserta los datos base con éxito!
La prueba de la función ConcurrencyCheck ha terminado
¡Actualización exitosa! Nota 1
¡La actualización es excepcional! Nota 2, ¡información anormal! La instrucción de actualización, inserción o eliminación de almacenar afectó un número inesperado de filas (0). Las entidades pueden haber sido modificadas o eliminadas desde que se cargaron las entidades. Consulte http://go.microsoft.com/fwlink/?LinkId=472540 para obtener información sobre cómo entender y gestionar las excepciones de concurrencia optimista.

Prueba la diferencia entre Timestamp y Concurrency Check
¡Actualización de UpdateTab1 exitosa! Nombre 1
¡Actualización de UpdateTab2 exitosa! Nombre 1
¡La actualización de la Pestaña 2 es anormal! Nombra 2, ¡información anormal! La instrucción de actualización, inserción o eliminación de almacenar afectó un número inesperado de filas (0). Las entidades pueden haber sido modificadas o eliminadas desde que se cargaron las entidades. Consulte http://go.microsoft.com/fwlink/?LinkId=472540 para obtener información sobre cómo entender y gestionar las excepciones de concurrencia optimista.
¡Actualización de UpdateTab1 exitosa! Nombre 2

【Marca de tiempo】
La característica TimeStamp puede aplicarse a la clase de campo, que solo tiene una propiedad de array de bytes, y esta característica establece el tipo tiemStamp en la columna. En comprobaciones concurrentes, Code-First utiliza automáticamente este campo tipo TimeStamp.

【Chequeo de concurrencia】
La característica ConcurrencyCheck puede aplicarse a las propiedades de una clase de dominio. Cuando EF realiza una operación de actualización, Code-First coloca el valor de la columna en la condición where, y puedes usar esta función CurrencyCheck para usar las columnas existentes para la verificación de concurrencia, en lugar de usar una columna de TimeStamp separada para la verificación de concurrencia.

¡Empecemos creando un nuevo objeto de contexto para demostrar la diferencia entre Timestamp y ConcurrencyCheck en el procesamiento de concurrencia!

Aquí tienes el código para el contexto:




Veamos las columnas de la base de datos, como sigue:



Veremos que tab1 y tab2 tienen columnas Id, Name y Remark, y tab 2 tiene más columnas RowVersion que tab1.

Adjunta primero el código de prueba:



【Principio de Verificación de Concurrencia】



Añadimos la función ConcurrencyCheck a la propiedad de Observación de la Pestaña 1,


Cuando actualizamos el valor del atributo Name de los mismos datos al mismo tiempo, ¡no se lanza ninguna excepción!


Generar sentencias SQL:


ejecutivo sp_executesql N'UPDATE [dbo]. [Tabuladora 1]
SET [Nombre] = @0
DONDE (([Id] = @1) Y ([Observación] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name1',@1=1,@2=N'Note1'
ejecutivo sp_executesql N'UPDATE [dbo]. [Tabuladora 1]
SET [Nombre] = @0
DONDE (([Id] = @1) Y ([Observación] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name2',@1=1,@2=N'note1'

Cuando actualizamos el valor de la propiedad Remark de los mismos datos al mismo tiempo, ¡lanzamos una excepción!

Generar sentencias SQL:

ejecutivo sp_executesql N'UPDATE [dbo]. [Tabuladora 1]
SET [Observación] = @0
DONDE (([Id] = @1) Y ([Observación] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note1',@1=1,@2=N'Note'
ejecutivo sp_executesql N'UPDATE [dbo]. [Tabuladora 1]
SET [Observación] = @0
DONDE (([Id] = @1) Y ([Observación] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note 2',@1=1,@2=N'Note'

Podemos ver que si tomamos el mismo dato con Id 1 al mismo tiempo, obtendremos el valor del atributo Remark, y al actualizar el atributo Remark, usaremos Remark como condición de actualización.

La primera instrucción sql puede actualizarse correctamente, y luego la observación cambia a "nota 1", y cuando se actualiza la segunda sentencia sql, la actualización fallará porque el valor de la observación ha cambiado.

【Principio de Marca de Tiempo】

Añadimos una propiedad RowVersion a Tab2 (puedes tomar cualquier nombre) y añadimos la función de marca temporal.



Cuando actualizamos el valor de Nombre de los mismos datos al mismo tiempo, la primera actualización tiene éxito, la segunda falla y se lanza una excepción, ¡echemos un vistazo al código sql generado!

ejecutivo sp_executesql N'UPDATE [dbo]. [Tab2]
SET [Nombre] = @0
DONDE ((([Id] = @1) Y ([RowVersion] = @2)) Y ([Observación] = @3))
SELECT [RowVersion]
DE [dbo]. [Tab2]
DONDE @@ROWCOUNT > 0 Y [Id] = @1',N'@0 nvarchar(max), @1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'Name1',@1=1,@2=0x00000000000007D1,@3=N'Note'
ejecutivo sp_executesql N'UPDATE [dbo]. [Tab2]
SET [Nombre] = @0
DONDE ((([Id] = @1) Y ([RowVersion] = @2)) Y ([Observación] = @3))
SELECT [RowVersion]
DE [dbo]. [Tab2]
DONDE @@ROWCOUNT > 0 Y [Id] = @1',N'@0 nvarchar(max), @1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'name2',@1=1,@2=0x00000000000007D1,@3=N'Note'

Al ejecutar la segunda sentencia SQL, como ya no se pueden encontrar los datos de la condición where, la actualización falla y se lanza una excepción.

Después de ejecutar con éxito la primera sentencia sql, el valor de RowVersion cambiará, como se muestra en la figura siguiente:





RowsVersion es una marca temporal

Solución temporal para actualizaciones perdidas   

Concepto de actualizaciones faltantes: Cuando los usuarios modifican una línea de datos al mismo tiempo, primero leen los datos, los colocan en el frontend para su modificación y luego envían los datos al modificarlos, de modo que los datos enviados finales sobrescriban los anteriores, lo que provoca la actualización perdida.

Resumiendo, aquí tienes formas de evitar perder actualizaciones:

Usa la marca de tiempo de RowsVersion.

Si una fila es inconsistente con el valor antes de la lectura, significa que otra transacción ha actualizado esa columna, de modo que esta columna no puede actualizarse, evitando así la pérdida de actualizaciones.



Finalmente, adjunta el código fuente:
CodeFirstDemo.rar (4.94 KB, Número de descargas: 13)




Anterior:Política de generación primaria nativa de claves nhibernate
Próximo:EF6 utiliza Database.BeginTransaction para gestionar transacciones
Publicado en 22/3/2022 11:51:38 |
Gracias por el esfuerzo, muy buen post
 Propietario| Publicado en 1/11/2023 20:42:15 |
La excepción de concurrencia EF DbUpdateConcurrencyException consulta el valor almacenado en caché
https://www.itsvse.com/thread-10692-1-1.html
 Propietario| Publicado en 27/12/2023 19:54:01 |
Declaraciones de migración generadas por rowversions optimizadas de bloqueos EF Core




Renuncia:
Todo el software, materiales de programación o artículos publicados por Code Farmer Network son únicamente para fines de aprendizaje e investigación; El contenido anterior no se utilizará con fines comerciales o ilegales; de lo contrario, los usuarios asumirán todas las consecuencias. La información de este sitio proviene de Internet, y las disputas de derechos de autor no tienen nada que ver con este sitio. Debes eliminar completamente el contenido anterior de tu ordenador en un plazo de 24 horas desde la descarga. Si te gusta el programa, por favor apoya el software genuino, compra el registro y obtén mejores servicios genuinos. Si hay alguna infracción, por favor contáctanos por correo electrónico.

Mail To:help@itsvse.com