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)
|