Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JTA Transactional Resource Implementation by Example

I'm trying to understand the basic principles of making a remote/networked resource compliant with JTA, and I'm thunderstruck by how little documentation/blogs/articles there are out there on the subject.

Say I have written my own special type of server, the "IAmYourFaja" server, or "IAYF". And let's say I wrote/implemented my very own TCP-based network protocol for interacting with this server, called IAYFCP (IAYF Comms Protocol). Finally, I wrote a Java client library for accessing and sending message to a remote IAYF server over IAYFCP. Still with me?

Now I have a use case where I need to do the following distributed transaction:

  1. Insert a record in a relational/JDBC database; then
  2. Fire a message to my IAYF server; then
  3. Push a message to a JMS broker

I need these to all transact so that if any one component fails at any point, I can roll all of them back and not have any altered state in these network resources.

The ultimate goal would be to be able to run the following code (pseudo-code here):

// "JTA Example"
DistributedTransaction dTrans = getTransaction();
DataSource jdbcDataSource = getDataSource();
IayfClient iayfClient = getIayfClient();
JmsClient jmsClient = getJmsClient();
try {
    dTrans.begin();

    // 1. Insert a record in a relational/JDBC database
    insertRecord(jdbcDataSource, "INSERT INTO widgets ( fizz, buzz ) VALUES ( 35, true )");

    // 2. Fire a message to my IAYF server
    iayfClient.fireMessage(IayfMessages.LukeIamYourFaja, 12);

    // 3. Push a message to a JMS broker
    jmsClient.publishMessage("Noooooooooo! (then jumps off ledge and Vader goes off to the bar)");

    // If we get here then all 3 networked resources are ready/capable of committing, so do it, do it now!
    dTrans.commit();
} catch(Throwable t) {
    // Something went wrong, roll back all 3.
    dTrans.rollback();
}

So the JDBC driver and JMS library I'm using are already JTA-compliant. This means that to make this code possible, I need to make my IAYF client library also JTA compatible. The problem is, I don't understand which JTA interfaces I would need to implement:

  • UserTransaction; or
  • XAResource

So a few questions:

  1. Which interface do I need to implement (and why): XAResource, UserTransaction, or both?
  2. Is that all I need to do to comply with JTA and make my IAYF client/service transactional? Anything else I need to do to make the "JTA Example" code above work as expected?
  3. True or false: Java EE containers have their own transaction managers that I could leverage with near-zero config, however, if I run my app in a non-Java EE/JTA compliant container, then I need to provide my own Transaction Manager, and could use something like Bitronix or Atomikos to accomplish this?
like image 286
IAmYourFaja Avatar asked Dec 13 '14 19:12

IAmYourFaja


People also ask

What is JTA implementation?

Java Transaction API (JTA) specifies standard Java interfaces between a transaction manager and the parties involved in a distributed transaction system: the resource manager, the application server, and the transactional applications.

How does JTA transaction work?

The Java™ Transaction API (JTA) allows applications to perform distributed transactions, that is, transactions that access and update data on two or more networked computer resources.

How is transaction implemented in Java?

The transaction manages the cache and synchronizes data with one database. Entity Objects are not directly exposed to the client tier. Instead, clients access an Entity Object's data through a View Object in an Application Module. All View Objects within the transaction share the same Entity Object caches.

Which transaction manager implementation would be most appropriate?

This is the preferred approach and works in most of the cases. Support for most of the transaction APIs such as JDBC, Hibernate, JPA, JDO, JTA etc. All we need to do is use proper transaction manager implementation class. For example org.


1 Answers

The UserTransaction interface is what you're using in your application (your pseudo-code above) to work with different resources. The DistributedTransaction would implement the UserTransaction interface. That DistributedTransaction object is your way to access the transaction manager.

In order for the transaction manager to carry out the distributed transaction against your 3 different resources, each needs to implement the XAResource interface and be registered somehow with the transaction manager. The details of how to register with the transaction manager depend on the implementation. For example see this section of the WebLogic documentation: Registering an XAResource to Participate in Transactions

So your client would implement XAResource and speak IAYFCP to your IAYF server. That also means that your IAYFCP protocol will need to support 2 phase commit.

Starting at section 3, this JBossTS documentation covers the XAResource interface too.

Yes, Bitronix, Atomikos and JBossTS are all listed as open source JTA implementations, according to this Wikipedia article on JTA. I suggest choosing one, implemeting a stub XAResource and then try registering your "Hello, world" XAResource with the transaction manager to see that it will make calls to your start/prepare/commit/rollback methods.

like image 112
Harold L Avatar answered Sep 18 '22 13:09

Harold L