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:
- Insert a record in a relational/JDBC database; then
- Fire a message to my IAYF server; then
- 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:
So a few questions:
- Which interface do I need to implement (and why):
XAResource
,UserTransaction
, or both? - 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?
- 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?
UserTransaction
, because this would be provided by the Transaction Manager, yes? – Apiculate