/ / ¿Por qué NHibernate Session.Save bloquea la base de datos? - sql-server, nhibernate, dotnetopenauth

¿Por qué NHibernate Session.Save bloquea la base de datos? - sql-server, nhibernate, dotnetopenauth

He creado una pequeña aplicación web ASP.NET MVC con NHibernate como ORM. En cada solicitud HTTP que comienza, creo una sesión y abro una transacción y la cierro al final de la solicitud.

// Begin request

session = StaticSessionManager.OpenSession();
session.BeginTransaction();

// End of request

currentSession.Transaction.Commit();
currentSession.Flush();
currentSession.Close();

Ahora también estoy usando DotNetOpenAuth API para Facebook / Google Login. Para poder registrar un nuevo usuario, la API espera que actualice una Tabla (por ejemplo, UserProfile) con cierta información del usuario. Esto lo estoy haciendo a través de Save () de Nhibernate

session.Save(new UserProfile { UserName = userName });

En la misma solicitud web, la API DotNetOpenAuth espera leer los datos insertados anteriormente de esa tabla (UserProfile).

Ahora esto está llevando a un escenario de punto muerto comoNHibernate "s Save aplicó algún tipo de bloqueo en la base de datos. Incluso cuando trato de leer manualmente los datos de esa tabla usando SQL Server Management Studio, parece esperar hasta que se agote el tiempo de espera de la solicitud web.

Ahora he intentado un enjuague explícito después de Guardar

session.Flush();

pero incluso esto no elimina el bloqueo. Quiero que mi API DotNetOpenAUth pueda leer los datos más actualizados.

Actualmente estoy comenzando la transacción después de guardar y volviendo a abrir una más después. No estoy seguro de si esta es la mejor práctica / tiene algún inconveniente.

Respuestas

4 para la respuesta № 1

¿Cuándo llamar a Flush?

Con la configuración predeterminada (FlushMode en ISession), llamando Commit() en la transacción NHibernate vaciará automáticamente los cambios. En algunas situaciones, queremos descargar manualmente, pero llamando Flush() después de la confirmación de la transacción es mala por varias razones:

  • Dado que el compromiso en sí ya se ha sonrojado, nosotrossepa que no hay más cambios en la descarga, por lo que es inútil. Sin embargo, NHibernate no sabe que es inútil, por lo que todavía revisará de manera sucia todos los objetos cargados.

  • Si de hecho hay algún estado sucio para enviar a la base de datos, dicha actualización se realizará fuera de la transacción, que generalmente no es lo que queremos.

Bloqueo de la base de datos

Normalmente, cuando la base de datos adquiere un bloqueo dede algún modo, ese bloqueo permanece hasta que se confirma la transacción o se realiza una copia de seguridad. El vaciado no termina una transacción y, por lo tanto, no tiene efecto de liberación en los bloqueos.

Intento de solucion

De su descripción parecería que ustedestán utilizando una conexión de base de datos (a través de la sesión NHibernate) para crear el UserProfile, y otra conexión de base de datos (en la misma solicitud web) para volver a leerlo. Esta conexión posterior se bloquea porque la transacción en la primera conexión aún no ha finalizado (claramente debe bloquearse, ya que la base de datos aún no sabe si la transacción será exitosa o no).

Intente encontrar una manera de hacer lo siguiente:

  • Cuando cree el perfil de usuario, hágalo en una transacción separada (y posiblemente en una sesión) que pueda confirmar antes de regresar.

  • O haga la "lectura" del perfil del usuariouse la misma conexión de base de datos, para que pueda hacerse dentro de la misma transacción. No estoy familiarizado con la API DotNetOpenAuth, pero veo si hay forma de anular la operación de lectura para que pueda hacerlo a través de NHibernate o, alternativamente, intente inyectar la sesión. Conexión en DotNetOpenAuth.