2008-10-10 17 views
7

Estamos tratando de crear un sistema de registro de pedidos de gran volumen. Hay tres tablas principales: 1. Las órdenes de 2. OrderDetails 3. OrderShipmentLINQ to SQL and Concurrency Issues

La tabla de envío contiene el registro n por pedido y cualquier entrada de registro de embarque pueden ser cambiados antes de que el cliente acepta º orden, después de lo cual es congelado. (Requisito empresarial)

Aunque esto no ocurra en los escenarios del mundo real ... durante nuestras pruebas de carga, obtenemos excepciones de System.Data.Linq.ChangeConflictException. Cerrar el envío dentro de una transacción tampoco está ayudando. ¿No podemos forzar a LINQ a obtener un bloqueo en la fila durante toda la operación de actualización?

¿Hay alguna otra forma de superar esto?

+0

¿Cómo estás manejando concurrencia LINQ? – flesh

Respuesta

7

Si tiene problemas reales con las actualizaciones simultáneas en los mismos datos, entonces podría considerar realizar toda la operación en una transacción, es decir, obtener los datos y comprometiéndolo. Siempre que trate el get/update/commit como una operación atómica de vida corta (es decir, no hace una pausa para la entrada del usuario en el medio), debería estar bien.

En particular, con un nivel de aislamiento serializable, nadie puede actualizar los datos que usted tiene un bloqueo de lectura en (es decir, todo lo que han buscado). El único problema es que esto podría conducir a escenarios de interbloqueo si las diferentes consultas están leyendo datos en diferentes órdenes. AFAIK, no hay forma de que LINQ-to-SQL emita la sugerencia (UPDLOCK), lo cual es una lástima.

Ya sea un TransactionScope o una SqlTransaction haría, siempre y cuando se establecen aislamiento como serializable (que es el valor predeterminado para TransactionScope).

+0

Hola, Gracias por la respuesta ... Yo probé envolviéndolo en virtud de una transacción, que acaba de obtener una excepción diferente ... que la operación es la víctima de un callejón sin salida. Saludos cordiales, Ashish Sharma –

+0

me preguntan si esto es un callejón sin salida lock-escalada, o un estancamiento orden diferente?Si lo primero, una opción (aunque pierde muchos de los beneficios de LINQ) podría ser consultar los datos con un SP, entonces puede incluir la sugerencia de UPDLOCK, lo que evita problemas de escalamiento de bloqueo. –

+0

(aún a través de LINQ, quiero decir, es decir, decirle al diseñador que este SP devuelve esta tabla) –

1

es posible que desee ver en Entity Framework que ejecuta todo como una transacción. Aquí hay dos podcasts que también pueden ser interesantes sobre Entity Framework.

DNRTV - part 1 - part 2

+1

LINQ-to-SQL también usa transacciones; el problema aquí es que la misma transacción no abarca el get y el set, pero eso es lo mismo con LINQ-to-SQL o EF. –

1

Para este tipo de situaciones, es decir, que más de un usuario puede querer realizar cambios en el mismo registro/cliente/pedido/lo que sea mejor para construir "bloqueo" en la lógica de la aplicación en lugar de utilizar los bloqueos de la base de datos.

el uso de bloqueos de base de datos para resolver bloqueo lógica de los datos que se va a presentar con un montón de nuevos problemas. Una mejor solución es tener columnas y/o tablas en las que pueda indicar que un usuario/cliente está editando una orden/un cliente, hasta que esté bloqueado, etc. Consulte esa tabla (o columnas) para verificar si el cliente/order/thing está disponible para editar antes de permitir que otro usuario lo edite.

Ver: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3984968&SiteID=1

+0

¿Podría reparar el enlace roto? – douglaslps

+0

Ojalá pudiera. Desafortunadamente, Microsoft ha actualizado los foros de MSDN y, en el proceso, eliminaron todos los enlaces a publicaciones/hilos, incluido el de arriba. El hilo todavía existe en alguna parte, pero no recuerdo cuál era ... – KristoferA