¿Cómo resolvería el problema de concurrencia con el siguiente código? En este ejemplo, nos gustaría saber por qué el usuario ha fallado la autenticación. El problema es que este código hace dos llamadas separadas a la base de datos, pero nos gustaría que todo el método ocurra dentro de una transacción conceptual. Específicamente estamos interesados en isolation. No queremos que las escrituras simultáneas durante la ejecución de este método afecten nuestras lecturas antes de que hayamos determinado el motivo del error de autenticación.Problemas de concurrencia con múltiples transacciones de bases de datos independientes?
Algunas soluciones vienen a la mente: Thread Locking, TransactionScope y Optimistic Locking. Realmente me gusta la idea de Optimistic Locking, ya que creo que los conflictos son raros, pero no hay nada integrado en .NET para hacer esto, ¿verdad?
Además, ¿hay algo de lo que DE VERDAD estar preocupado en este caso? ¿Cuándo es importante tener en cuenta los problemas de concurrencia y cuándo no? ¿Qué debe considerarse al implementar una solución? ¿Actuación? La duración del bloqueo? ¿Cuán probables son los conflictos?
Editar: Después de revisar respuesta Aristos', creo que lo que estoy realmente después es algún tipo de nivel de aislamiento 'snapshot' para el método de autenticación.
public MembershipStatus Authenticate(string username, string password)
{
MembershipUser user = Membership.GetUser(username);
if (user == null)
{
// user did not exist as of Membership.GetUser
return MembershipStatus.InvalidUsername;
}
if (user.IsLockedOut)
{
// user was locked out as of Membership.GetUser
return MembershipStatus.AccountLockedOut;
}
if (Membership.ValidateUser(username, password))
{
// user was valid as of Membership.ValidateUser
return MembershipStatus.Valid;
}
// user was not valid as of Membership.ValidateUser BUT we don't really
// know why because we don't have ISOLATION. The user's status may have changed
// between the call to Membership.GetUser and Membership.ValidateUser.
return MembershipStatus.InvalidPassword;
}
No estoy seguro de que realmente necesita preocuparse por el aislamiento aquí. ¿Cuáles son las posibilidades de que un usuario sea eliminado o bloqueado entre la llamada a 'GetUser' y' ValidateUser'? Y más al punto, no debes exponer esta información al usuario de todos modos. Si muestra diferentes mensajes para "contraseña incorrecta" frente a "usuario no existe" frente a "cuenta bloqueada", alguien que intente hackear su sitio puede aprovechar esa información para obtener una lista de nombres de usuario válidos.No desea eso, ya que esos nombres de usuario pueden ser útiles para explotar alguna otra vulnerabilidad en su infraestructura. –
+1 para la respuesta. Probablemente usado un mal ejemplo aquí (aunque yo estaba pensando en la distinción entre "credenciales no válidas" y "Cuenta bloqueada" y tal vez tengo que reconsiderar eso). ¡Simplemente no me gusta el hecho de que los datos puedan cambiar debajo de mí! La concurrencia es difícil! ¿Qué sucede si NECESITO que los datos sean constantes, qué sugeriría? – Brandon