1 2 3 4 Previous Next 50 Replies Latest reply on Sep 11, 2018 4:49 AM by tomjenkinson Go to original post
      • 15. Re: Using Narayana to make two RESTful services transactional
        txuser

        I tried with @Transactional attribute again and I get "Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL". I do have DB_CLOSE_ON_EXIT=FALSE in dbConfig, Am I missing any configuration for h2 database?

         

        Caused by: org.springframework.transaction.HeuristicCompletionException: Heuristic completion: outcome state is mixed; nested exception is javax.transaction.HeuristicMixedException

        at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1028)

        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)

        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)

        at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)

        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)

        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)

        at org.jboss.narayana.quickstart.spring.service.ExampleService$$EnhancerBySpringCGLIB$$76a910f8.testTransaction(<generated>)

        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

        at java.lang.reflect.Method.invoke(Method.java:497)

        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:139)

        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:295)

        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:249)

        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:236)

        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:402)

        ... 50 more

        Caused by: javax.transaction.HeuristicMixedException

        at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1296)

        at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:126)

        at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:89)

        at org.jboss.tm.usertx.client.ServerVMClientUserTransaction.commit(ServerVMClientUserTransaction.java:193)

        at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1021)

        ... 67 more

        Suppressed: javax.transaction.xa.XAException: Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-171]

        at org.h2.jdbcx.JdbcXAConnection.convertException(JdbcXAConnection.java:397)

        at org.h2.jdbcx.JdbcXAConnection.prepare(JdbcXAConnection.java:238)

        at com.arjuna.ats.internal.jta.resources.arjunacore.XAResourceRecord.topLevelPrepare(XAResourceRecord.java:214)

        at com.arjuna.ats.arjuna.coordinator.BasicAction.doPrepare(BasicAction.java:2664)

        at com.arjuna.ats.arjuna.coordinator.BasicAction.doPrepare(BasicAction.java:2614)

        at com.arjuna.ats.arjuna.coordinator.BasicAction.prepare(BasicAction.java:2157)

        at com.arjuna.ats.arjuna.coordinator.BasicAction.End(BasicAction.java:1503)

        at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:96)

        at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:162)

        at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1288)

        ... 71 more

        Caused by: org.h2.jdbc.JdbcSQLException: Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-171]

        at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)

        at org.h2.message.DbException.get(DbException.java:169)

        at org.h2.message.DbException.get(DbException.java:146)

        at org.h2.message.DbException.get(DbException.java:135)

        at org.h2.jdbc.JdbcConnection.checkClosed(JdbcConnection.java:1391)

        at org.h2.jdbc.JdbcConnection.checkClosed(JdbcConnection.java:1366)

        at org.h2.jdbc.JdbcConnection.createStatement(JdbcConnection.java:192)

        at org.h2.jdbcx.JdbcXAConnection.prepare(JdbcXAConnection.java:234)

        ... 79 more

        • 16. Re: Using Narayana to make two RESTful services transactional
          tomjenkinson

          Hi,

           

          Are you able to provide some kind of reproducer code and the configuration files you are using too?

           

          Changing the code to TransactionAttribute sounded a little strange, can you provide that part?

           

          At your first message you talked about using Oracle but now you have moved to h2 I see?

           

          There must be somewhere where the URL for H2 is not getting that element of the H2 config I would think - if you can share a reproducer it will be easier to spot.

           

          Many thanks,

          Tom

          • 17. Re: Using Narayana to make two RESTful services transactional
            txuser

            Hi,

             

            I wanted to use Oracle. But for now, I am trying with H2 because that is the database in the example (quickstart/spring/jta at master · jbosstm/quickstart · GitHub ) . following is the datasource configuration.

             

            @Bean

                public XADataSource h2DataSource() {

                    JdbcDataSource ds = new JdbcDataSource();

                    ds.setURL("jdbc:h2:target/test.db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE);

                    ds.setUser("sa");

                    ds.setPassword("");

                    return ds;

                }

             

             

            I have @Transactional now and still same error.  Below is my sample code.

             

             

            @GET

            @Produces({ "application/json" })

            @Transactional

            @Path("/insert/{trigger}")

            public Response testTransaction(@PathParam("trigger") int trigger) {

             

             

            try {

            jdbc.execute("delete from example");

             

             

            int count = testCommits(trigger);

            return (Response.status(Response.Status.OK).entity("first get " + count).build());

             

             

            } catch (Exception ex) {

            Integer count = jdbc.queryForObject("select count(*) from example", Integer.class);

             

             

            return Response.status(Response.Status.BAD_REQUEST)

            .entity(ex.getMessage() + " count in db in first get" + count).build();

             

             

            } finally {

            shutdownDatabase();

            TxControl.disable(true);

            TransactionReaper.terminate(true);

            }

             

             

            }

             

            public int testCommits(int trigger) throws Exception {

            try {

             

             

            Transaction transaction = tm.getTransaction();

            xaResource.setFault(DummyXAResource.faultType.HALT);

            transaction.enlistResource(xaResource);

            jdbc.execute("insert into example values (1, 'test2')");

             

             

            if (trigger == 1) {

            jdbc.execute("insert into example values (1, 'test3')");

            } else {

            jdbc.execute("insert into examples values (1, 'test3')");

             

             

            }

            return jdbc.queryForObject("select count(*) from example", Integer.class);

            } catch (Exception e) {

            Integer count = jdbc.queryForObject("select count(*) from example", Integer.class);

            throw new BadRequestException("insereted entries " + count + "exception" + e.getMessage());

            }

            }

             

             

            Thank you

            • 18. Re: Using Narayana to make two RESTful services transactional
              zhfeng

              I think quickstart/spring/jta at master · jbosstm/quickstart · GitHub  is designed as the standalone application and I have the following questions:

               

              1. Do you want to deploy the sample service in the container (such as the Wildfly) ?

              2. Or you want to run with the spring-boot framework ?

              3. How do you call this sample service from the other service ? Do you want to propagate the transaction between the services ?

               

              Thanks,

              Amos

              • 19. Re: Using Narayana to make two RESTful services transactional
                txuser

                Hi Amos.

                 

                I was able to run standalone app successfully. Please see below.

                 

                1. I made it a web app and deployed to wildfly10 ( included web.xml and change the type to war is the only change I did)

                2. I am not using spring boot. I use just Spring.

                3. For now I have only 1 web service.If transaction works on one web service, my plan is to call another rest web service with in the main one .

                • 20. Re: Using Narayana to make two RESTful services transactional
                  zhfeng

                  Thanks Sewwandi,  and I'm going to understand your scenario.

                   

                  There are two transactional RESTful service A and B, and service C will invoke these two services in one transaction. The codes look like

                  TxSupport txn = new TxSupport(coordinatorUrl); // get a helper for using REST Atomic Transactions
                  Client client = ClientBuilder.newClient(); // get a JAX-RS Client
                  
                  txn.startTx(); // start a REST Atomic transaction
                  
                  client.target("http://serviceA").path().post(); // invoke the Service A
                  client.target("http://serviceB").path().post(); // invoke the Service B
                  
                  txn.commitTx(); // commit the transaction and the server A and B will update the data
                  // txn.rollbackTx(); // rollback the transaction and A and B will not change the data
                  
                  

                  Dose this make sense with your requirement about the transactional RESTful services ?

                   

                  Amos

                  • 21. Re: Using Narayana to make two RESTful services transactional
                    txuser

                    Thanks Amos. This is exactly what I want to do. The issue I have is, I am not able to get one web service transactional. I get "Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL". I do have DB_CLOSE_ON_EXIT=FALSE in dbConfig, Am I missing any configuration for h2 database?

                    • 22. Re: Using Narayana to make two RESTful services transactional
                      tomjenkinson

                      Is it possible to share a simplified version of your app so we can try to run it here?

                      • 23. Re: Using Narayana to make two RESTful services transactional
                        mmusgrov

                        txuser  wrote:

                         

                        I started with spring JTA quickstart. I modified the project little bit to have two inserts and made second insert fail.

                        Did you manage to successfully run the jta-service quickstart quickstart? This is the quickstart that uses REST to JTA bridging and it assumes that you start the transaction via the REST-AT support.

                        I think trying to convert the spring JTA quickstart before getting the REST to JTA bridging example running first is the wrong approach.

                        • 24. Re: Using Narayana to make two RESTful services transactional
                          tomjenkinson

                          What is shutdownDatabase doing?

                          • 25. Re: Using Narayana to make two RESTful services transactional
                            tomjenkinson

                            What is ;AUTO_SERVER=TRUE for?

                            • 26. Re: Using Narayana to make two RESTful services transactional
                              tomjenkinson

                              What does the web.xml look like for you?

                              • 27. Re: Using Narayana to make two RESTful services transactional
                                txuser

                                Hi,

                                 

                                I added shutdownDatabase after call the process because I saw connections are not closing properly.  Please see below. Also I read in h2 database document, if we have AUTO_SERVER=TRUE, then it will allowe read write access always.

                                 

                                 

                                 

                                @GET

                                @Produces({ "application/json" })

                                @Transactional

                                @Path("/insert/{trigger}")

                                public Response testTransaction(@PathParam("trigger") int trigger) {

                                 

                                 

                                try {

                                jdbc.execute("delete from example");

                                 

                                 

                                int count = testCommits(trigger);

                                return (Response.status(Response.Status.OK).entity("first get " + count).build());

                                 

                                 

                                } catch (Exception ex) {

                                Integer count = jdbc.queryForObject("select count(*) from example", Integer.class);

                                 

                                 

                                return Response.status(Response.Status.BAD_REQUEST)

                                .entity(ex.getMessage() + " count in db in first get" + count).build();

                                 

                                 

                                } finally {

                                shutdownDatabase();

                                //TxControl.disable(true);

                                //TransactionReaper.terminate(true);

                                }

                                 

                                 

                                }

                                 

                                 

                                Please see my web.xml.

                                 

                                <?xml version="1.0" encoding="UTF-8"?>

                                <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"

                                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                                xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

                                 

                                 

                                <display-name>ExfoProvisioning RESTful web service</display-name>

                                 

                                 

                                <context-param>

                                <param-name>log4jConfiguration</param-name>

                                <param-value>file:///${env:JBOSS_HOME}/standalone/configuration/log4j2.xml</param-value>

                                </context-param>

                                 

                                 

                                <!-- Creates the Spring Container shared by all Servlets and Filters extending

                                ContextLoaderListener -->

                                <listener>

                                <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>

                                </listener>

                                 

                                 

                                <listener>

                                <listener-class>net.tds.adm.mss.api.listener.SpringContextLoaderListener</listener-class>

                                </listener>

                                 

                                 

                                <!-- Processes application requests -->

                                <context-param>

                                <param-name>resteasy.servlet.mapping.prefix</param-name>

                                <param-value>/ws</param-value>

                                </context-param>

                                <servlet>

                                <servlet-name>appServlet</servlet-name>

                                <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>

                                </servlet>

                                <servlet-mapping>

                                <servlet-name>appServlet</servlet-name>

                                <url-pattern>/ws/*</url-pattern>

                                </servlet-mapping>

                                 

                                 

                                 

                                 

                                <login-config>

                                <auth-method>BASIC</auth-method>

                                <realm-name>RESTful web service</realm-name>

                                </login-config>

                                 

                                 

                                 

                                 

                                 

                                 

                                <security-role>

                                <role-name>admin</role-name>

                                </security-role>

                                <security-role>

                                <role-name>read-write</role-name>

                                </security-role>

                                 

                                 

                                <security-constraint>

                                <web-resource-collection>

                                <web-resource-name>All resources</web-resource-name>

                                <url-pattern>/ws/*</url-pattern>

                                </web-resource-collection>

                                <auth-constraint>

                                <role-name>admin</role-name>

                                <role-name>read-write</role-name>

                                </auth-constraint>

                                </security-constraint>

                                 

                                 

                                <security-constraint>

                                <web-resource-collection>

                                <web-resource-name>Public</web-resource-name>

                                <url-pattern>/ws/status</url-pattern>

                                </web-resource-collection>

                                </security-constraint>

                                 

                                 

                                 

                                 

                                 

                                 

                                </web-app>

                                • 28. Re: Using Narayana to make two RESTful services transactional
                                  tomjenkinson

                                  I don't think that net.tds.adm.mss.api.listener.SpringContextLoaderListener would work here. Also, is there meant to be a applicationContext.xml somewhere.

                                   

                                  It really would be easier to share a cut down maven project on GitHub so we can try to help you best.

                                  • 29. Re: Using Narayana to make two RESTful services transactional
                                    tomjenkinson

                                    Also, you didn't show the shutdownDatabase routine yet.