Pregunta

Está usando la palabra clave 'sincronizado' en métodos en un DAO de Java que van a causar problemas cuando son utilizados por una aplicación web?

Lo pregunto porque tengo una aplicación independiente de múltiples subprocesos que necesita a los métodos de sincronización para evitar conflicto de recursos, como se ve aquí.

java.util.concurrent.ExecutionException: javax.persistence.PersistenceException: org.hibernate.HibernateException: Found shared references to a collection: com.replaced.orm.jpa.Entity.stuffCollection

¿Qué me preocupa es que cuando un número significativo de personas tratar de utilizar la aplicación que los métodos sincronizados bloquearán y retrasar la aplicación completa hacia abajo.

Estoy utilizando un resorte inyecta APP fábrica gestor de la entidad, lo que proporciona un gestor de la entidad a la DAO. Trasladase técnicamente la capa DAO y tienen las clases llame a la fábrica gestor de la entidad directamente, pero disfrutar de la separación de la DAO proporciona.

También debo señalar que estoy siendo muy cuidadoso para no pasar entidad alrededor de objetos conectados entre hilos ORM. Mi hipótesis es que el error de conflicto de recursos se produce cuando se accede a la DAO. Creo que múltiples hilos van al mismo tiempo, y tratar de persistir o leer de la base de datos de manera no atómicas.

En este caso se utiliza un DAO va a hacer más daño entonces ayudar?


Una gran parte de la información que me fui fuera de la cuestión es que la DAO no es un producto único. Si hubiera estado pensando lucidez suficiente para incluir ese detalle que probablemente no habría hecho la pregunta en el primer lugar.

Si he entendido bien, Primavera crea una nueva instancia de la clase DAO para cada clase que lo utiliza. Por lo que el administrador de entidades de soporte debe ser único para cada hilo. No compartir el gestor de la entidad es, como respondió Rob H, la clave aquí.

Sin embargo, ahora no entiendo por qué se producen errores cuando quito sincronizada.


De acuerdo con esta hilo , la anotación @PersistenceContext crea un thread- SharedEntityManager seguro. Por lo que debe ser capaz de crear un producto único DAO.

¿Fue útil?

Solución

Usted dice que no está compartiendo objetos de entidad a través de las discusiones. Eso es bueno. Pero también debe asegurarse de que no estás compartiendo EntityManager objetos (o Session objetos en hibernación) a través de hilos tampoco. Marcos como Spring gestionar esto automáticamente mediante el almacenamiento de la sesión en una variable local de subprocesos. Si va a codificar sus propias DAOs sin la ayuda de un marco, es necesario tomar precauciones mismo, para evitar compartirlas.

Una vez hecho esto, no debería haber ninguna razón para sincronizar métodos DAO porque ninguno de los estado conversacional será compartida a través de las discusiones. Esto es crítico para una aplicación web altamente concurrente. La alternativa es que sólo un hilo será capaz de acceder a la DAO en un momento, suponiendo que todos ellos comparten la misma instancia de DAO. No es bueno en absoluto para el rendimiento.

Otros consejos

Si necesita ser sincronizado para la seguridad hilo, luego dejarlos allí. El bloqueo se requiere de todos modos en ese caso. Si no se requiere el bloqueo para el caso de aplicaciones web, puede:

  • dejarlo como está, ya que el rendimiento golpeado cuando no hay contención en el bloqueo es insignificante, y insignificante cuando se toma en cuenta expensas de golpear la base de datos.
  • Rediseño de modo que se agrega una capa de sincronización para el caso de aplicación independiente que protege el subyacente DAO no sincronizada.

En lo personal, me gustaría dejarlo como está y el perfil para ver si es necesario refactorizar. Hasta entonces simplemente está haciendo la optimización prematura.

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