10 Replies Latest reply on May 6, 2017 3:11 PM by tomjenkinson

    JTS StandAlone<->Spring  Setup

    mina.azib

      Im new to Narayana and JBoss in general, so I'm having a bit of difficulty setting up JTS to work with Spring.

       

      I did the following:

      1. Execute jts-jacorb-setup-env.[bat|sh] to put Narayana in the classpath

      2. Copy default-jts-jbossts-jacorb-properties.xmlin to your CWD and rename it to jbossts-properties.xml

      3. Put jacorb.properties into C:\Users\Mina\Documents\jacorb_config\etc\

      4. ./bin/start-transaction-service.[bat|sh]

      5. I followed the instructions  from JBossTransactionsWithSpring on the application side

       

      JTS starts started with -Djacorb.config.dir=C:\Users\Mina\Documents\jacorb_config and seems ok. The output looks like this:

      INFO: base configuration loaded from classpath orb.properties

      May 02, 2017 9:55:24 PM org.jacorb.config.JacORBConfiguration init

      INFO: configuration jacorb loaded from file C:\Users\Mina\Documents\jacorb_config\etc\jacorb.properties

      2017-05-02 21:55:24.156 INFO Property "jacorb.hashtable_class" is set to: java.util.Hashtable

      2017-05-02 21:55:24.166 WARNING Warning - unknown codeset (Cp1252) - defaulting to ISO-8859-1

      2017-05-02 21:55:24.171 INFO InterceptorManager started with 1 Server Interceptors, 1 Client Interceptors and 1 IOR Interceptors

      2017-05-02 21:55:24.239 INFO oid:

      00 19 39 0E 34 20 4A 3D 01 3F 02                            ..9.4 J=.?.

      object is activated

      2017-05-02 21:55:24.242 INFO Using server ID (3382179795) for transient POA

      2017-05-02 21:55:24.274 INFO base configuration loaded from classpath orb.properties

      2017-05-02 21:55:24.276 INFO configuration jacorb loaded from file C:\Users\Mina\Documents\jacorb_config\etc\jacorb.properties

      2017-05-02 21:55:24.276 INFO created ORBSingleton

      2017-05-02 21:55:24.353 INFO ClientConnectionManager: created new ClientGIOPConnection to 192.168.1.168:53032 (6b143ee9)

      Ready

      2017-05-02 21:55:24.361 INFO ORB run

       

       

      I dont see my main application connecting to JTS through Jacorb

      The output looks like this:

      INFO: Using JTA UserTransaction: org.springframework.transaction.jta.UserTransactionAdapter@5136d012

      May 02, 2017 8:06:23 PM org.springframework.transaction.jta.JtaTransactionManager checkUserTransactionAndTransactionManager

      INFO: Using JTA TransactionManager: com.arjuna.ats.internal.jta.transaction.jts.TransactionManagerImple@5939a379

      May 02, 2017 8:06:23 PM com.arjuna.ats.arjuna.recovery.TransactionStatusManager start

      INFO: ARJUNA012170: TransactionStatusManager started on port 51874 and host 127.0.0.1 with service com.arjuna.ats.arjuna.recovery.ActionStatusService

       

      So to me this indicates its launching a local transaction manager - so how do i configure it to the stand alone JTS?

       

       

      The Configuration in my application:

       

        <jdbc:embedded-database id="dataSource" type="H2" >

        <jdbc:script location="classpath:create-db.sql" />

        </jdbc:embedded-database>

       

        <bean id = "UserDAOImpl" class="spring_app.UserDAOImpl">

        <property name = "dataSource" ref="dataSource"/>

        </bean>

       

        <tx:annotation-driven transaction-manager="transactionManager" />

       

        <bean id="jbossTransactionManager" class="com.arjuna.ats.internal.jta.transaction.jts.TransactionManagerImple">

        </bean>

       

        <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">

          <property name="transactionManager">

            <ref bean="jbossTransactionManager"></ref>

          </property>

        </bean>

       

      The Main code in my application

       

      public static void main(String[] args) throws InvalidName, SystemException {

       

       

              com.arjuna.orbportability.ORB myORB = com.arjuna.orbportability.ORB.getInstance("NameService");

              com.arjuna.orbportability.RootOA myOA = com.arjuna.orbportability.OA.getRootOA(myORB);

              myORB.initORB(args, null);

       

       

       

              ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

              // HelloWorld obj = (HelloWorld) context.getBean("helloWorld");

              // obj.getMessage();

       

       

              UserDAO userDAOImpl = (UserDAO) context.getBean("UserDAOImpl");

       

       

              User user = new User();

              user.setId(100);

              user.setEmail("blah");

              user.setName("Name");

       

       

              Address address = new Address();

              address.setAddress("address");

              address.setCountry("country");

              address.setId(2000);

       

       

              user.setAddress(address);

       

       

              userDAOImpl.create(user);

              List<User> users = userDAOImpl.getUsers();

              System.out.println(users);

          }

       

       

      I start my application with -Djacorb.config.dir=C:\\Users\\Mina\\Documents\\jacorb_config

       

      So in sum I dont know how to get the components to talk via Jacorb. Any guidance will be appreciated! Thank you!

        • 1. Re: JTS StandAlone<->Spring  Setup
          zhfeng

          Hi Mina,

           

          How did the UserDAOImpl look like ? Do you use the hibernate ?

           

          I noticed that you had use the <jdbc:embedded-database> and I'm not sure it supports the XA ? Maybe you need to use the Transactional Driver. See the other discuss

          Narayana JTS with Spring in Tomee

           

          Hope it is helpful !

          Amos

          • 2. Re: JTS StandAlone<->Spring  Setup
            tomjenkinson

            Hi, and thanks for your interest in Narayana!

             

            Unfortunately we don't have an example of JTS with Spring at this time, however there is an interesting example of how to run an external transaction manager over here:

            https://github.com/jbosstm/quickstart/tree/master/jts-docker/src/test/java/org/jboss/narayana/jts/docker

             

            In that scenario we are using docker containers and a name service to share the IOR of the transaction manager.

             

            In the docs you could search for CONFIGURATION_FILE (the default in the jbossts-properties.xml) to see the intended way to share the IOR via a file:

            Narayana Project Documentation

             

            Once you get this working, I am wondering how you are intending to propagate the transaction context (this is often done via EJB libraries but it doesn't have to be).

             

            Thanks,

            Tom

            • 3. Re: JTS StandAlone<->Spring  Setup
              mina.azib

              Hi Amos,

               

              No I did not use Hibernate at all. I used straight jdbc. See the following

               

              private JdbcTemplate jdbcTemplateObject;

                  private DataSource   dataSource;

               

               

                  @Override

                  public void setDataSource(DataSource dataSource) {

                      this.dataSource = dataSource;

                      this.jdbcTemplateObject = new JdbcTemplate(dataSource);

               

               

                  }

               

               

                  @Override

               

               

                  @Transactional(propagation = Propagation.REQUIRED, readOnly = false)

                  public void create(User user) {

                      String SQL = "insert into users(id,name,email) values (?,?,?)";

                      jdbcTemplateObject.update(SQL, user.getId(), user.getName(), user.getEmail());

               

               

                      System.out.println("Inserted into Customer Table Successfully");

                      System.out.println("Create new user = " + user.getName());

                      SQL = "insert into Address(id,address,country) values (?,?,?)";

                      jdbcTemplateObject.update(SQL, user.getAddress().getId(), user.getAddress().getAddress(),

                              user.getAddress().getCountry());

                      System.out.println("Inserted into Address Table Successfully");

               

               

                  }

               

               

                  @Override

                  public User getUser(String name) {

                      String SQL = "select * from users where name = '?'";

                      User user = jdbcTemplateObject.queryForObject(SQL, new Object[] { name }, new UserMapper());

                      return user;

                  }

               

               

                  @Override

                  public List<User> getUsers() {

                      String SQL = "select * from users";

                      List<User> users = jdbcTemplateObject.query(SQL, new UserMapper());

                      return users;

               

               

                  }

              }

              • 4. Re: JTS StandAlone<->Spring  Setup
                mina.azib

                Hi Tom,

                 

                I tried using a name service(NS.bat) with Jacorb but I dont think I have the jacorb configuration correct between Narayana, the Jacorb Name Server, and the Spring application. I think that's the final piece I have missing. According to the Spring documentation a Transaction Manager *should* be an easily plug in via configuration, so just trying to get there. I assumed with the configuration file I have in Spring, that Narayana would just link up and semi-automatically work.

                 

                This might just be my lack of knowledge in Jacorb at this point. I am still investigating.

                 

                I ran the name server using: ns -Djacorb.naming.ior_filename=d:/IR_Ref -DOAPort=38693

                I ran nmg and am able to connect to the name server using nmg -ORBInitRef.NameService=file:///d:/IR_Ref

                 

                However I dont know the correct way to get the transaction manager to connect to the nameserver.

                Ive tried adding the following to the end of the command in "start-transaction-server.bat":

                -Djacorb.naming.ior_filename=d:/IR_Ref

                -ORBInitRef.NameService=file:///d:/IR_Ref

                 

                @Amos Feng

                 

                I switched out the data source to use an actual MySql instance:

                <bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

                    <property name="driverClassName" value="com.mysql.jdbc.Driver" />

                    <property name="url" value="jdbc:mysql://localhost:3306/test_spring" />

                    <property name="username" value="root" />

                    <property name="password" value="password" />

                </bean>

                 

                but that didnt change anything as the output from my spring program was still:

                -ORBInitRef.NameService=file:///d:/IR_Ref

                May 03, 2017 12:08:22 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh

                INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6442b0a6: startup date [Wed May 03 12:08:22 PDT 2017]; root of context hierarchy

                May 03, 2017 12:08:22 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

                INFO: Loading XML bean definitions from class path resource [Beans.xml]

                May 03, 2017 12:08:22 PM org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName

                INFO: Loaded JDBC driver: com.mysql.jdbc.Driver

                May 03, 2017 12:08:22 PM org.springframework.transaction.jta.JtaTransactionManager checkUserTransactionAndTransactionManager

                INFO: Using JTA UserTransaction: org.springframework.transaction.jta.UserTransactionAdapter@5cee5251

                May 03, 2017 12:08:22 PM org.springframework.transaction.jta.JtaTransactionManager checkUserTransactionAndTransactionManager

                INFO: Using JTA TransactionManager: com.arjuna.ats.internal.jta.transaction.jts.TransactionManagerImple@433d61fb

                May 03, 2017 12:08:22 PM com.arjuna.ats.arjuna.recovery.TransactionStatusManager start

                INFO: ARJUNA012170: TransactionStatusManager started on port 56989 and host 127.0.0.1 with service com.arjuna.ats.arjuna.recovery.ActionStatusService

                 

                 

                My expectation is that there is some configuration that needs to be done in the spring application that tells it where the name server is. After the nameserver is connected to the transaction service is linked up with the spring application. But up to this point I am having a problem having anyone connect to the Jacorb name server besides nmg.

                 

                Thanks,

                Mina

                • 5. Re: JTS StandAlone<->Spring  Setup
                  tomjenkinson

                  Can I check though, you are sure you want JTS behaviour (and not just a JTA?)

                  • 6. Re: JTS StandAlone<->Spring  Setup
                    mina.azib

                    Well from my understanding (which I may be very wrong). JTA is when you use transactions within a container such as JBoss, EJB, etc.. What i am looking to do is have a distributed system where various regular old java programs are modifying databases at the same time and needed a global transaction solution to coordinate this. My assumption was that using Spring and annotations and defining a transaction manager(JTS) that adhered to JTA that it would be wired up to work correctly.

                     

                    Also I am able to get the JTS to connect to the jacorb nameserver now by changing the jbossts-properties.xml to be

                    <entry key="OrbPortabilityEnvironmentBean.bindMechanism">NAME_SERVICE</entry>

                    and including running the start-transaction-service.bat as follows:

                    "%JAVA_HOME%\bin\java"  com.arjuna.ats.jts.TransactionServer -ORBInitRef.NameService=file:///d:/IR_Ref

                     

                    So the only last piece seems to be to get the spring app to talk to both...

                    • 7. Re: JTS StandAlone<->Spring  Setup
                      tomjenkinson

                      Hi Mina,

                       

                      You need the same config in the Spring app:

                      <entry key="OrbPortabilityEnvironmentBean.bindMechanism">NAME_SERVICE</entry>

                       

                      I want to check with you though, you say the various java programs modify the database at the same time, but do you want:
                      A>  those different updates in the different JVMS to be be within the same transaction or

                      B> you just want ACID on the updates and access in each process?

                       

                      If its B you don't actually need JTS to do that. Simple JTA will do that as the database will know what to do with the XA directives to keep updates and access compliant with ACID.

                       

                      However, if its A then JTS is a good approach to take. The difficulty you will have as you are using Spring is that you will need to take care of the transaction propagation yourself I believe, JTS has good integration with EJBs but I am not aware of out-of-the-box integration for transaction propagation with Spring remote services. If you think about this without transactions for the moment, can you let me know what feature of spring you are using to invoke from a service in JVM A to a service in JVM B so I can try to work out what will help to propagate the TX. If you are doing your own propagation (i.e just calling a remote CORBA service) we have a demo app (quite old now!) that has propagation and doesn't use EJB: quickstart/ArjunaJTS/trailmap at master · jbosstm/quickstart · GitHub the fact the services extend CosTransactions::TransactionalObject mean that they will be invoked with the context (assuming the rest of the environment is JTS aware quickstart/Bank.idl at master · jbosstm/quickstart · GitHub

                       

                      Hope that helps,
                      Tom

                      • 8. Re: JTS StandAlone<->Spring  Setup
                        tomjenkinson

                        If you aren't working with CORBA already, another option for this would be REST-AT as that also bridges from a transport to JTA.

                        • 9. Re: JTS StandAlone<->Spring  Setup
                          mina.azib

                          Hi Tom,

                           

                          Thank you for your reply. I think that might have been my confusion. To be more exact there are going to be multiple instances of a java program that will need to do multiple updates within a transaction on the same database. So more concretely

                           

                          Instance 1:on different jvm or server

                          Begin Transaction

                          Update table 1

                          Update table 2

                          Update table 3

                          End Transaction

                           

                          Instance 2:on different jvm or server

                          Begin Transaction

                          Update table 1

                          Update table 2

                          Update table 3

                          End Transaction

                           

                          So its not many programs participating in the same transaction rather its many concurrent transactions on the same tables within different JVM/Servers.

                           

                          So being able to have the N instances running in a distributed environment and not have them step on each others transaction is what I was hoping to achieve. So i assumed I had to have the transaction propagate to a transaction management solution so that it could see the transaction status and coordinate them. And none of the applications are within an application server, you can think of them as distributed workers on a big data system. So would SimpleJTA work in this case? Or im thinking this is more of a general architecture issue I need to resolve.

                           

                          Thanks,

                          Mina

                          • 10. Re: JTS StandAlone<->Spring  Setup
                            tomjenkinson

                            Ah, yes JTS is not required for the use case you describe. You can run Narayana without JTS in Spring to achieve the outcome you are looking for. We have several examples that show this under: quickstart/spring at master · jbosstm/quickstart · GitHub

                             

                            Best wishes,

                            Tom

                            1 of 1 people found this helpful