2009-07-19 17 views
7

En primer lugar, permítanme dar una breve descripción del escenario. Estoy escribiendo un juego simple donde casi todo el trabajo se realiza en el lado del servidor con un cliente ligero para que los jugadores puedan acceder a él. Un jugador inicia sesión o crea una cuenta y luego puede interactuar con el juego moviéndose alrededor de una cuadrícula. Cuando ingresan a una celda, deben ser informados de otros jugadores en esa celda y, de manera similar, se informará a los demás jugadores de esa celda de ese jugador que ingresa. Hay muchas otras interacciones y acciones que pueden tener lugar, pero no vale la pena entrar en detalles sobre ellas, ya que es más de lo mismo. Cuando un jugador cierra la sesión y vuelve a entrar o si el servidor se cae y vuelve a subir, todo el estado del juego debería persistir, aunque si el servidor falla, no importa si pierdo 10 minutos o más de cambios.¿Gestión de sesiones de NHibernate?

He decidido utilizar NHibernate y una base de datos SQLite, así que he estado leyendo mucho en NHibernate, siguiendo tutoriales y escribiendo algunas aplicaciones de muestra, ¡y estoy completamente confundido en cuanto a cómo debo hacerlo!

La pregunta que tengo es: ¿cuál es la mejor manera de administrar mis sesiones? Sólo a partir de la pequeña cantidad que yo entiendo, todas estas posibilidades saltan a mí:

  • Tener una sola sesión que siempre abiertos que todos los clientes utilizar
  • tener una sola sesión para cada cliente que se conecta y al ras periódicamente
  • Abrir una sesión cada vez que tenga que usar cualquiera de las entidades persistentes y cerrarla tan pronto como la actualización, inserción, eliminación o consulta esté completa
  • Tener una sesión para cada cliente, pero mantenerla desconectada y solo vuelva a conectarlo cuando necesite usarlo
  • Sam e que el anterior, pero mantenerlo conectado y sólo se desconecte después de un cierto período de inactividad
  • Mantenga las entidades adosados ​​y sólo les adjunte cada 10 minutos, por ejemplo, para confirmar los cambios

¿Qué tipo de estrategia debería Utilizo para obtener un rendimiento decente dado que podría haber muchas actualizaciones, insertos, eliminaciones y consultas por segundo de posiblemente cientos de clientes a la vez, y todos deben ser coherentes entre sí?

Otra pregunta más pequeña: ¿cómo debo usar las transacciones de manera eficiente? ¿Está bien que cada cambio sea en su propia transacción, o va a funcionar mal cuando tengo cientos de clientes tratando de alterar las celdas de la grilla? ¿Debo tratar de averiguar cómo agrupar las actualizaciones similares y colocarlas en una sola transacción, o eso será demasiado complicado? ¿Necesito transacciones para la mayor parte?

Respuesta

8

Usaría una sesión por solicitud en el servidor y una transacción por sesión. No optimizaría el rendimiento antes de que la aplicación esté madura.

respuesta a sus soluciones:

  • tener una sola sesión que siempre abiertos que todos los clientes utilizar: Usted tendrá problemas de rendimiento aquí porque la sesión no se hilo de seguridad y tendrán que bloquear todas las llamadas al sesión.
  • Tenga una sola sesión para cada cliente que se conecta y vacíe periódicamente: Aquí tendrá problemas de rendimiento porque todos los datos utilizados por el cliente se almacenarán en caché.También verá problemas con los datos obsoletos de la memoria caché.
  • Abra una sesión cada vez que tenga que usar cualquiera de las entidades persistentes y ciérrela tan pronto como se complete la actualización, inserción, eliminación o consulta: aquí no tendrá ningún problema de rendimiento. Una desventaja es la posibilidad de concurrencia o problemas de datos corruptos debido a que las sentencias SQL relacionadas no se ejecutan en la misma transacción.
  • Tenga una sesión para cada cliente, pero manténgala desconectada y solo vuelva a conectarla cuando la necesite: NHibernate ya tiene una administración de conexión incorporada y está muy optimizada.
  • Igual que el anterior, pero manténgalo conectado y solo desconéctelo después de un cierto período de inactividad: causará problemas debido a que la cantidad de conexiones sql es limitada y también limitará la cantidad de usuarios de su aplicación.
  • Mantenga las entidades separadas y solo conéctelas cada 10 minutos, por ejemplo, para confirmar los cambios: Causará problemas debido a datos obsoletos en las entidades separadas. Tendrá que hacer un seguimiento de los cambios usted mismo, lo que le hará terminar con un código que se parece a la sesión en sí.

Sería inútil entrar en más detalles ahora, porque simplemente repetiría los manuales/tutoriales/libros. Cuando utiliza una sesión por solicitud, probablemente no tendrá problemas en el 99% de la aplicación que describe (y tal vez en absoluto). La sesión es una clase liviana y no peligrosa, que es muy corta. Cuando desee saber exactamente cómo funciona la gestión de la sesión/conexión/caché/transacción, le recomiendo que lea primero un manual y luego haga algunas preguntas más detalladas sobre los temas poco claros.

+0

No estoy tratando de optimizarlo; Solo estoy tratando de descubrir cuáles son los diferentes métodos para hacerlo, para qué son generalmente buenos o no, qué tan bien se escalan y funcionan, etc. antes de comprometerse con uno. Se trata de asegurarme de no hacer nada estúpido y elegir una solución razonablemente sensata. No ajuste de rendimiento. Entonces, en cuanto a su respuesta, ¿qué quiere decir con "solicitud" - qué "solicitud"? ¿Te refieres a cada vez que un jugador hace algo? – IRBMe

+0

Sí con la solicitud me refiero a "cada vez que un jugador hace algo" o "cada llamada del cliente al servidor" – Paco

+0

Después de leer las ediciones que agregó más adelante, tengo una pregunta sobre algo que usted dijo.En cuanto a tener una sola sesión por cliente, pensé que NHibernate garantiza que los métodos como ISession.Find nunca devolverán datos obsoletos. En segundo lugar, parecías desalentado al usar Reconexión/Desconexión porque "NHibernate ya tiene una administración de conexión integrada", pero el manual usa eso en un ejemplo de concurrencia llamado "Larga sesión con control automático de versiones". – IRBMe

0

Mi objetivo es mantener todo en la memoria, y el diario cambia o toma instantáneas periódicas sin conexión.

+0

Ya pensé en esta solución y va a ser mucho más complicada, esencialmente duplicando muchas de las funciones de fiabilidad que me proporciona una base de datos. Es por eso que decidí ir con una base de datos en primer lugar, en lugar de simplemente escribir todos los datos en archivos planos o algo así. – IRBMe

1

Lea el 'ISessionFactory' en este page de la documentación de NHibernate. ISession s están diseñados para ser de un solo subproceso (es decir, no seguro para subprocesos) lo que probablemente significa que no debe compartirlo entre los usuarios. ISessionFactory debe ser creado una vez por su aplicación y debe crearse ISession s para cada unidad de trabajo. Recuerde que la creación de un ISession s no necesariamente da como resultado la apertura de una conexión de base de datos. Eso depende de cómo esté configurada la estrategia de agrupación de conexiones de SessionFactory.

Es posible que también desee consultar la Documentación de Hibernate en Session and Transaction.

0

Lea a través de NHibernate Best Practices with ASP.NET, hay algunos consejos muy buenos aquí para comenzar. Como ya se mencionó, tenga mucho cuidado con una ISession ya que NO es segura, así que téngalo en cuenta.

Si necesita algo un poco más complejo, eche un vistazo al proyecto contrib NHibernate.Burrow. Establece algo así como "el poder real que proporciona Burrow es que una conversación de Burrow puede abarcar varias solicitudes de HTTP".

Cuestiones relacionadas