Comportamiento extraño con @Transactional (propagation = Propagation.REQUIRES_NEW)

Aquí está mi problema:

Estoy ejecutando un lote en una aplicación Java EE / Spring / Hibernate. Este lote llama amethod1. Este método llama amethod2 que puede lanzarUserException (una clase que se extiendeRuntimeException). Así es como se ve:

@Transactional
public class BatchService implements IBatchService {
 @Transactional(propagation=Propagation.REQUIRES_NEW)
 public User method2(User user) {
   // Processing, which can throw a RuntimeException
 }

 public void method1() {
   // ...
   try {
     this.method2(user);
   } catch (UserException e) {
     // ...
   }
   // ...
 }
}

La excepción se captura mientras la ejecución continúa, pero al final demethod1 cuando se cierra la transacción se lanza una excepción RollbackException.

Aquí está la traza de la pila:

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:476)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy128.method1(Unknown Source)
at batch.BatchController.method1(BatchController.java:202)

Cuandomethod2 No está lanzando esta excepción, funciona bien.

Lo que he intentado:

Ajuste@Transactional(noRollbackFor={UserException.class})) enmethod1Tratar de atrapar enmethod2

Pero no cambió nada.

Como la excepción se produce en una transacción diferente en la que se produjo una reversión, no entiendo por qué no funciona. He echado un vistazo a esto:Transacción Jpa javax.persistence.RollbackException: Transacción marcada como rollbackOnly pero realmente no me ayudó.

Estaré muy agradecido si alguien me pudiera dar una pista.

Actualizar

Lo he hecho funcionar estableciendopropagation=Propagation.REQUIRES_NEW en el método llamado pormethod2 (que es en realidad el que está enviando la excepción). Este método se define en una clase muy similar a miBatchService. Así que no veo por qué funciona en este nivel y no enmethod2.

He puestomethod2 tan público como la anotación@Transactional no se tiene en cuenta si el método es privado como se dice en la documentación:

La anotación @Transactional puede colocarse antes de una definición de interfaz, un método en una interfaz, una definición de clase o un método público en una clase.

También traté de usarException en lugar deRuntimeException (ya que es más apropiado) pero tampoco cambió nada.

Incluso si está funcionando, la pregunta permanece abierta ya que tiene un comportamiento extraño y me gustaría entender por qué no está actuando como debería.

Respuestas a la pregunta(1)

Su respuesta a la pregunta