-
15. Re: Using Narayana to make two RESTful services transactional
txuser Aug 27, 2018 4:14 PM (in response to 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 Aug 28, 2018 4:54 AM (in response to txuser)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 Aug 28, 2018 10:41 AM (in response to tomjenkinson)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 Aug 29, 2018 4:24 AM (in response to txuser)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 Aug 29, 2018 10:31 AM (in response to zhfeng)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 Sep 4, 2018 10:40 AM (in response to txuser)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 Sep 4, 2018 3:15 PM (in response to zhfeng)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 Sep 4, 2018 3:48 PM (in response to txuser)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 Sep 5, 2018 8:24 AM (in response to txuser)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 Sep 6, 2018 9:43 AM (in response to txuser)What is shutdownDatabase doing?
-
25. Re: Using Narayana to make two RESTful services transactional
tomjenkinson Sep 6, 2018 9:44 AM (in response to txuser)What is ;AUTO_SERVER=TRUE for?
-
26. Re: Using Narayana to make two RESTful services transactional
tomjenkinson Sep 6, 2018 10:05 AM (in response to txuser)What does the web.xml look like for you?
-
27. Re: Using Narayana to make two RESTful services transactional
txuser Sep 6, 2018 10:32 AM (in response to tomjenkinson)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 Sep 6, 2018 1:34 PM (in response to txuser)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 Sep 6, 2018 1:34 PM (in response to tomjenkinson)Also, you didn't show the shutdownDatabase routine yet.