Pregunta

Necesito poder crear una nueva entidad de usuario sólo si El correo electrónico proporcionado es único.

Siempre he manejado esto antes realizando un simple if (!UserSet.Any(...)) antes de mi AddToUserSet(...). Sin embargo, esta no es una solución concurrente y se romperá bajo una carga pesada.

He estado investigando las transacciones, pero AFAIK también necesitaría establecer un Updlock en la selección, pero EF4 no admite esto.

¿Cómo manejan esto todos los demás?

¿Fue útil?

Solución

Puede forzar el bloqueo incluyendo selección en transacción:

using (var scope = new TransactionScope())
{
    // Create context
    // Check non existing email
    // Insert user
    // Save changes
}

Esto utilizará la transacción serializable, que es lo que necesita si desea una solución concurrente para insertos: Updlock no es suficiente para garantizar que no se agregue un nuevo registro durante su transacción.

Esto puede ser bastante malo cuello de botella, así que estoy de acuerdo con @Paolo: simplemente coloque la restricción única a la base de datos y captura la excepción durante el inserto si el correo electrónico no es único.

Transacción serializable de Libros en línea:

Especifica lo siguiente:

    Statements cannot read data that has been modified but not yet  
    committed by other transactions.

    No other transactions can modify data that has been read by the  
    current transaction until the current transaction completes.

    Other transactions cannot insert new rows with key values that
    would fall in the range of keys read by any statements in the current
    transaction until the current transaction completes.

Los bloqueos de rango se colocan en el rango de valores clave que coinciden con las condiciones de búsqueda de cada declaración ejecutadas en una transacción. Esto bloquea otras transacciones para actualizar o insertar cualquier fila que califique para cualquiera de las declaraciones ejecutadas por la transacción actual. Esto significa que si alguna de las declaraciones en una transacción se ejecutan por segunda vez, leerán el mismo conjunto de filas. Los bloqueos de rango se mantienen hasta que se completa la transacción. Este es el más restrictivo de los niveles de aislamiento porque bloquea rangos de llaves enteros y sostiene las cerraduras hasta que se completa la transacción. Debido a que la concurrencia es menor, use esta opción solo cuando sea necesario. Esta opción tiene el mismo efecto que la configuración de HoldLock en todas las tablas en todas las declaraciones selectas en una transacción.

Otros consejos

Además de su cheque, puede agregar un restricción única En el campo de correo electrónico directamente en el DB

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