2010-03-02 14 views
27

Estoy usando CMT en beans de sesión sin estado EJB3. También creé mi propia excepción con la anotación "@ApplicationException (rollback = true)".Retroceso de transacción EJB3

  1. ¿Tengo que usar "context.setRollbackOnly()" cuando quiero deshacer la transacción?

  2. ¿Puedo simplemente retrotraer la transacción arrojando una excepción dentro del método público en el bean?

  3. Si es así (la respuesta a Q # 2 es sí) ¿Tengo que arrojar la excepción del método declarando la excepción en el método o bastará con arrojar una excepción dentro del método y manejarlo? está dentro del mismo método en sí? (No quiero propagar la excepción al siguiente nivel. Solo quiero deshacer la excepción.)

Gracias de antemano. ;)

Respuesta

62

En primer lugar, no hay reversión de una excepción, es una reversión de una transacción.

  1. Si lanza su excepción con @ApplicationException(rollback=true), no tiene que deshacer la transacción manualmente. Context.setRollbackOnly() obliga al contenedor a deshacer la transacción, también si no hay una excepción.
  2. Una excepción comprobada en sí misma no revierte una transacción. Necesita tener la anotación @ApplicationException(rollback=true). Si la excepción es RuntimeException y la excepción no se detecta, obliga al contenedor a deshacer la transacción. Pero cuidado, el contenedor descartará en este caso la instancia de EJB.
  3. Como se menciona en 2.), si lanza un RuntimeException, la transacción se retrotraerá automáticamente. Si detecta una excepción marcada dentro del código, debe usar setRollbackOnly para deshacer la transacción.

Para obtener más información, consulte el libro gratuito Mastering EJB. Describe muy bien los escenarios de retrotracción y se puede descargar gratis.

+0

"Si detecta una excepción marcada dentro del código, debe usar setRollbackOnly para deshacer la transacción". ¿Se puede lanzar la misma excepción y deshacer la transacción? –

+0

Puede lanzar la misma excepción con la cláusula throws, pero la transacción no se revierte. Si desea deshacer la transacción en este caso, debe agregar @ApplicationException (rollback = true) a su excepción. Otra forma es ajustar la excepción marcada dentro de una excepción no verificada (por ejemplo, RuntimeException). Pero de esta manera no se prefiere realmente, porque si se lanza una RuntimeException, el contenedor descarta la instancia de bean y crea una nueva. – Steve

+1

Solo estaba viendo esta respuesta por razones similares y quiero señalar que el libro al que enlazas ya no se ofrece en su totalidad en ese sitio, y es de 2006, por lo que está terriblemente anticuado y probablemente no sea de mucha utilidad en JEE5 y contextos JEE6. – BillR

0

La cuestión de cómo evitar que las excepciones comprobadas anotadas declaradamente causen una reversión al lanzar desde la propagación a la "capa superior" todavía no se responde aquí.

Creo que esto requerirá una envoltura alrededor del EJB en cuestión que se traga la excepción lanzada. (En otras palabras: creo que la excepción personalizada DEBE lanzarse contra el límite de método (y por lo tanto no atrapado & procesado dentro del método) Y propagarse para tener efecto transaccional, y también a su vez causará la destrucción de la instancia EJB.)