4 Replies Latest reply on Jun 12, 2006 12:37 AM by kumachan

    About the Transaction rollback of the container management i

    kumachan

      Hello.
      I have a stateless session bean, entity bean, servlet program.
      When SQL exception happens, the rollback cannot be done though the method of the session bean is called from the servlet.
      When the Runtime Exception is compulsorily generated in the session bean, the roll backing is done.
      However, the following exceptions are thrown out for an actual SQL exception, and the roll backing is not done.
      How should I do to do the roll backing?
      May I have advice?


      Servlet Class:

       public Value doBiz(Hashtable param, HttpServletRequest req){
       String page = "/jsp/test/TestEntryEnd.jsp";
       Value value = new Value();
      
       try{
       TestUserBean usrs = new TestUserBean();
       usrs.setTestUserId(1);
       usrs.setTestName("test name");
      
       /* DB insert */
       TestService service = new TestService();
       service.insertTestUser(usrs);
      
       /* To cause the exception, the data of same ID is inserted again. */
       TestUserBean usrs2 = new TestUserBean();
       usrs2.setTestUserId(1);
       usrs2.setTestName("test name2");
      
       service.insertTestUser(usrs2);
      
       value.setForwardPage(page);
       }catch(Exception ex){
       System.out.println("***** TestEntryEnd.doBiz catch ex = " + ex);
       value.addErrorMessage("TestEntryEnd Error");
       value.setError(true);
       }
       return value;
       }
      






      Stateless Session Bean Class:
      @Stateless
      @Local(TestSession.class)
      @Remote(TestSession.class)
      
      public class TestSessionBean implements TestSession{
       @PersistenceContext
       protected EntityManager em;
      
       @TransactionAttribute(TransactionAttributeType.REQUIRED)
       public void insertTestUser(TestUserBean usrs){
       em.persist(usrs);
      
       /* When the exception is compulsorily caused here, the roll backing is done. */
       //throw new RuntimeException("!! RuntimeException !?");
       }
      }
      



      Error stack trace
      11:33:30,354 WARN [JDBCExceptionReporter] SQL Error: 0, SQLState: null
      11:33:30,355 ERROR [JDBCExceptionReporter] Batch entry 0 insert into testuser (testName, testUserId) values (7, 7) was aborted. Call getNextException to see the cause.
      11:33:30,355 WARN [JDBCExceptionReporter] SQL Error: 0, SQLState: 23505
      11:33:30,355 ERROR [JDBCExceptionReporter] ERROR: duplicate key violates unique constraint "testuser_pkey"
      11:33:30,356 ERROR [AbstractFlushingEventListener] Could not synchronize database state with session
      org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
      at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:69)
      at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
      at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:202)
      at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:91)
      at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:86)
      at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:171)
      at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2048)
      at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2427)
      at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:51)
      at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:243)
      at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:227)
      at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
      at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296)
      at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
      at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1009)
      at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:356)
      at org.hibernate.transaction.CacheSynchronization.beforeCompletion(CacheSynchronization.java:59)
      at org.jboss.tm.TransactionImpl.doBeforeCompletion(TransactionImpl.java:1473)
      at org.jboss.tm.TransactionImpl.beforePrepare(TransactionImpl.java:1092)
      at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:306)
      at org.jboss.aspects.tx.TxPolicy.endTransaction(TxPolicy.java:175)
      at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:87)
      at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:192)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
      at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
      at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:54)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
      at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:78)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
      at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
      at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
      at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:178)
      at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:74)
      at $Proxy115.insertTestUser(Unknown Source)
      at TestService.insertTestUser(TestService.java:29)
      at TestEntryEnd.doBiz(TestEntryEnd.java:71)
      at TestServlet.service(TestServlet.java:95)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
      at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
      at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)
      at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:159)
      at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
      at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
      at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
      at java.lang.Thread.run(Thread.java:595)
      Caused by: java.sql.BatchUpdateException: Batch entry 0 insert into testuser (testName, testUserId) values (7, 7) was aborted. Call getNextException to see the cause.
      at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2497)
      at org.postgresql.core.v3.QueryExecutorImpl$1.handleError(QueryExecutorImpl.java:399)
      at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1298)
      at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:347)
      at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2559)
      at org.jboss.resource.adapter.jdbc.WrappedStatement.executeBatch(WrappedStatement.java:487)
      at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
      at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
      ... 57 more


        • 1. Re: About the Transaction rollback of the container manageme
          guidoscalise

          SQLException extends Exception, not RuntimeException.

          EJB Specs say that if a RuntimeException is thrown in a transactional EJB method, the associated transaction is rolledback automatically.
          But for plain Exceptions (non RuntimeExceptions), like the one you are getting, the container doesn't rollback automatically (as there's a chance that the user might want to retry the operation). In order to cause the transaction to rollback, you need to call sessionContext.setRollbackOnly(), which will mark the transaction to avoid commital.

          Note: EJB Specs talk about System Exceptions and Application Exceptions, not about checked-unchecked nor runtime-nonruntime, I just explained quickly with runtime-nonruntime, but you should read the Specs anyway.

          Also, you might want to read the book Enterprise JavaBeans [Bill Burke, Sacha Labourey and Richard Monson-Haefel], specially chapter 16, part 6: "Exceptions and Transactions".

          Kind regards,
          Guido Scalise

          • 2. Re: About the Transaction rollback of the container manageme
            guidoscalise

            I should add that, in EJB3, there's an Annotation for business methods, in order to force Rollback if an ApplicationException is thrown from the method:
            @ApplicationException(rollback=true)

            Cheers,
            Guido Scalise

            • 3. Re: About the Transaction rollback of the container manageme
              kumachan

              Thank you for the reply.

              Rollback cannot be still done though '@ApplicationException(rollback=true)' was added to SessionBean.
              Is this a cause though the method of the business is in servlet?

              Stateless Session Bean Class:

              @Stateless
              @Local(TestSession.class)
              @Remote(TestSession.class)
              @ApplicationException(rollback=true)
              
              public class TestSessionBean implements TestSession{
               @PersistenceContext
               protected EntityManager em;
              
               @TransactionAttribute(TransactionAttributeType.REQUIRED)
               public void insertTestUser(TestUserBean usrs){
               em.persist(usrs);
              
               /* When the exception is compulsorily caused here, the roll backing is done. */
               //throw new RuntimeException("!! RuntimeException !?");
               }
              }
              



              • 4. Re: About the Transaction rollback of the container manageme
                kumachan

                Hello.
                'org.jboss.tm.JBossRollbackException' is generated, and rollback cannot be done though RuntimeException came to be able to do
                in catche by using '@ApplicationException(rollback=true)' as advised.
                Is there a problem in the writing of the code?
                Or, is it a setting of Jboss and is there anything necessary?
                May I have the known person advice?
                It asks suitably.



                My Exception Class:

                @ApplicationException(rollback=true)
                public class MyAppException extends Exception{
                
                 public MyAppException(){}
                 public MyAppException(String msg){
                 super(msg);
                 }
                }
                



                Stateless Session Bean Class:
                @Stateless
                @Local(TestSession.class)
                @Remote(TestSession.class)
                
                public class TestSessionBean implements TestSession{
                 @PersistenceContext
                 protected EntityManager em;
                
                 @TransactionAttribute(TransactionAttributeType.REQUIRED)
                 public void insertTestUser(TestUserBean usrs) throws MyAppException{
                 em.persist(usrs);
                 }
                }
                



                Servlet Class:
                 public Value doBiz(Hashtable param, HttpServletRequest req){
                 String page = "/jsp/test/TestEntryEnd.jsp";
                 Value value = new Value();
                
                 try{
                 TestUserBean usrs = new TestUserBean();
                 usrs.setTestUserId(1);
                 usrs.setTestName("test name");
                
                 /* DB insert */
                 TestService service = new TestService();
                 service.insertTestUser(usrs);
                
                 /* To cause the exception, the data of same ID is inserted again. */
                 TestUserBean usrs2 = new TestUserBean();
                 usrs2.setTestUserId(1);
                 usrs2.setTestName("test name2");
                
                 service.insertTestUser(usrs2);
                
                 value.setForwardPage(page);
                 }catch(Exception ex){
                 System.out.println("***** TestEntryEnd.doBiz catch ex = " + ex);
                 value.addErrorMessage("TestEntryEnd Error");
                 value.setError(true);
                 }
                 return value;
                 }
                


                Error stack trace
                12:30:14,603 WARN [JDBCExceptionReporter] SQL Error: 0, SQLState: null
                12:30:14,603 ERROR [JDBCExceptionReporter] Batch entry 0 insert into testmail (testMail, testUserId, testMailId) values (13, 13, 13) was aborted. Call getNextException to see the cause.
                12:30:14,603 WARN [JDBCExceptionReporter] SQL Error: 0, SQLState: 23505
                12:30:14,603 ERROR [JDBCExceptionReporter] ERROR: duplicate key violates unique constraint "testmail_pkey"
                12:30:14,604 ERROR [AbstractFlushingEventListener] Could not synchronize database state with session
                org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
                at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:69)
                at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
                at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:202)
                at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:230)
                at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
                at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296)
                at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
                at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1009)
                at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:356)
                at org.hibernate.transaction.CacheSynchronization.beforeCompletion(CacheSynchronization.java:59)
                at org.jboss.tm.TransactionImpl.doBeforeCompletion(TransactionImpl.java:1473)
                at org.jboss.tm.TransactionImpl.beforePrepare(TransactionImpl.java:1092)
                at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:306)
                at org.jboss.aspects.tx.TxPolicy.endTransaction(TxPolicy.java:175)
                at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:87)
                at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:192)
                at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
                at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
                at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
                at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:54)
                at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
                at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:78)
                at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
                at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
                at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
                at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
                at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:98)
                at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:178)
                at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:74)
                at $Proxy112.insertTestMail(Unknown Source)
                at TestService.insertTestMail(TestService.java:55)
                at TestEntryEnd.doBiz(TestEntryEnd.java:73)
                at TestServlet.service(TestServlet.java:95)
                at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
                at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
                at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)
                at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:159)
                at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
                at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
                at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
                at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
                at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
                at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
                at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
                at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
                at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
                at java.lang.Thread.run(Thread.java:595)
                Caused by: java.sql.BatchUpdateException: Batch entry 0 insert into testmail (testMail, testUserId, testMailId) values (13, 13, 13) was aborted. Call getNextException to see the cause.
                at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2497)
                at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1298)
                at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:347)
                at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2559)
                at org.jboss.resource.adapter.jdbc.WrappedStatement.executeBatch(WrappedStatement.java:487)
                at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
                at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
                ... 50 more
                12:30:14,616 INFO [STDOUT] ***** TestEntryEnd.doBiz catch ex = java.lang.RuntimeException: org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=22, BranchQual=, localId=22] status=STATUS_NO_TRANSACTION; - nested throwable: (org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update)