2010-10-04 17 views
16

Estoy escribiendo una aplicación web que admite varios usuarios. Cada usuario tiene su propia base de datos, utilizando H2. todos los esquemas de base de datos son iguales.Orígenes de datos multiusuario - Spring + Hibernate

Deseo usar Spring + Hibernate para esta aplicación.

Así que estoy atascado en cómo asociar la base de datos de un usuario con ese usuario, tal vez lo asocie en la sesión HTTPSession, y extienda Spring's AbstractRoutingDataSource? pero, ¿no afectaría esto a la memoria caché de Hibernate? Otra forma es tener una SessionFactory con cada fuente de datos, aunque el esquema de cada fuente de datos sea el mismo ... así que lo veo como un desperdicio.

De todos modos, la selección de la fuente de datos debe ser dinámica: no se pueden preconfigurar en archivos de contexto, ya que cada nuevo usuario tendrá su propia base de datos creada. ¿Hay marcos/soluciones existentes?

No sé demasiado sobre Hibernate Shards, ¿quizás funciona?

Respuesta

8

I podría estar equivocado acerca de la (estricto) necesita tener una SessionFactory por base de datos, como sugieren algunos recursos:

voy a tomar algún tiempo para que todo vuelva a leer mañana (no he tenido todos los detalles para ser honesto) y para entender completamente las implicaciones de tal disposición (aunque parece claro que romperá el caché de segundo nivel). Volveré sobre esto más tarde.


Estoy escribiendo una aplicación web que soporta múltiples usuarios. Cada usuario tiene su propia base de datos, utilizando H2. todos los esquemas de base de datos son iguales.

Me pregunto cómo va a escalar ... ¿Cuántos usuarios tiene? ¿Cómo se ejecuta H2, qué modo?

Así que estoy atascado en la forma de asociar la base de datos de un usuario con ese usuario - tal vez asociado en el HttpSession, y extender AbstractRoutingDataSource de primavera?

Vas a tener que construir un SessionFactory por usuario y asociarlo al usuario que ha iniciado (en un Map, utilizando el nombre de usuario como la clave) y luego obtener una Session de un determinado SessionFactory. Vincular el ciclo de vida del SessionFactory a la sesión HTTP parece ser una buena idea (para guardar algo de memoria) pero no estoy seguro de que Spring sea de gran ayuda aquí. Podría estar equivocado, pero una variación de la clase HibernateUtil y un enfoque totalmente programático parece más fácil. No estoy seguro de que necesite múltiples conexiones por usuario por cierto.

pero este efecto no es el caché de Hibernate?

¿Qué caché?

Otra forma es tener una SessionFactory con cada fuente de datos, aunque el esquema de cada fuente de datos sea el mismo ... así que lo veo como un desperdicio.

Oh, es un desperdicio, pero eso es lo que quiere hacer (una base de datos por usuario). Y no tiene la opción (necesita uno SessionFactory por base de datos). ¿Por qué necesita una base de datos por usuario en realidad? ¿Estás seguro de que esta es una decisión sabia? Como ya se sugirió, esto significa muchos problemas, no se escalará bien, agrega complejidad, etc. ¿Por qué no utilizar una sola base de datos y asociar datos al usuario?

De todos modos, la selección de la fuente de datos debe ser dinámica: no se pueden preconfigurar en archivos de contexto, ya que cada nuevo usuario tendrá su propia base de datos creada. ¿Hay marcos/soluciones existentes?

No lo tengo. Y también por eso creo que tendrás que hacer todo programáticamente.

No sé demasiado sobre Hibernate Shards, ¿quizás funcione?

Dadas las necesidades dinámicas de su aplicación, no veo cómo podría ayudar.

+0

Hola Pascal, gracias por su respuesta. Todas las bases de datos tienen el mismo esquema, por lo que una SessionFactory para todas estas bases de datos estaría bien. Hibernate tiene un caché de segundo nivel, que puede contener datos caché no válidos si cargo 2 entidades únicas desde 2 bases de datos diferentes pero con los mismos ID. Creo que puedo hacer que esto funcione al asociar el DataSource con una HttpSession y el uso de un Interceptor para conectar el DataSource en la HttpSession a ThreadLocal para que mi impl AbstractDataSource pueda obtener el DS correcto para la transacción. – Dzhu

+0

+1 para el artículo de Ken DeLong - me salvó algunos dolores de cabeza :-) – opyate

1

Gracias a la ayuda de las 2 personas (Pascal y org.life.java)!

Es posible, pero con algunos problemas: p. hibernación caché de segundo nivel/caché de consultas.

Este enlace suministrado por Pascal es un recurso muy bueno:

http://www.jroller.com/kenwdelong/entry/horizontal_database_partitioning_with_spring.

Mi principal motivación para dar a cada usuario una base de datos separada es que es probable que los datos crezcan rápidamente, por lo que se requiere una división horizontal.

Cuestiones relacionadas