2010-04-01 20 views
23

Acabo de querer sus opiniones de expertos sobre gestión de transacciones declarativas para Spring. Aquí está mi configuración:Spring - Transaction Readonly

  1. capa DAO es viejo y simple JDBC utilizando Spring JdbcTemplate (n Hibernate, etc)
  2. capa de servicio es POJO con transacciones declarativas de la siguiente manera - save*, readonly = false, rollback for Throwable

cosas funcionan bien con encima de la configuración. Sin embargo, cuando digo get*, readonly = true, veo errores en mi archivo de registro que dicen Database connection cannot be marked as readonly. Esto sucede para todos los métodos get * en la capa de servicio.

Ahora mis preguntas son:

A. ¿Hay que establecer get* como de sólo lectura? Todos mis métodos get* son operaciones de lectura pura DB. No deseo ejecutarlos en ningún contexto de transacción. ¿Qué tan grave es el error anterior?

B. Cuando elimino la configuración get*, no veo los errores. Además, todas mis operaciones simples get* se realizan sin transacciones. ¿Es este el camino a seguir?

C. ¿Por qué alguien querría tener métodos transaccionales donde readonly = true? ¿Hay algún significado práctico de esta configuración?

¡Gracias! Como siempre, ¡sus respuestas son muy apreciadas!

Respuesta

23

This post indica que el comportamiento o el indicador readOnly depende del mecanismo de persistencia.

C. Sí, cuando se utiliza de hibernación, da beneficios en el rendimiento ajustando el modo ras de FLUSH_NEVER (como se describe en el post vinculado)

B. Sí, llamadas JDBC no requieren una transacción (hibernate requiere uno), por lo que la eliminación de la configuración @Transactional recorta toda la gestión de transacciones.

A. Me asumir la primavera está llamando connection.setReadOnly(true) pero su controlador JDBC no admite esta

La línea de fondo es: no utilice readonly transacciones con JDBC normal.

Y otra cosa: se supone que las transacciones abarcan consultas múltiples. No haga sus transacciones demasiado detalladas. Conviértelos a unit of work.

+0

Gracias Bozho! Claro como el día. Supongo que eliminaré la configuración de get * porque estoy usando JDBC normal. – AAK

+1

Sin una transacción de solo lectura, también se abre a la temida 'org.hibernate.LazyInitializationException'. – HDave

+0

De qué manera puedo evitar org.hibernate.LazyInitializationException al demandar a waffle authntication manager. –

5

A. ¿Debo decir get * as readonly? Todos mis métodos get * son operaciones de lectura pura DB. No deseo ejecutarlos en ningún contexto de transacción. ¿Qué tan grave es el error anterior?

En realidad, es probable que todavía desea ejecutar todas sus get() s en el contexto de una transacción, para asegurarse de que está recibiendo las lecturas consistentes. Si, por otro lado, no te importa esto, puedes establecer el nivel de transacción en consecuencia.

C. ¿Por qué alguien querría tener métodos transaccionales donde readonly = true? ¿Hay algún significado práctico de esta configuración?

  1. Para ayudar a proteger contra las escrituras andantes dentro get() `métodos
  2. Para fines de optimización. Hibernate no solo puede hacer uso de esta información, como lo mencionó Bozho, sino que algunas bases de datos/controladores JDBC también pueden hacer uso de esta información.
+0

Gracias Matt! Supongo que mis métodos get * son consultas de selección de SQL independientes bastante simples y no estoy usando Hibernate, por lo que desactivo la configuración. – AAK

Cuestiones relacionadas