Wednesday, February 3, 2016

Narayana Updates

Greetings from the Narayana team!

5.2.13.Final Released

We are very proud to announce the latest release of our project and its available for download now from http://narayana.io/
The release notes for this version are available here:
https://issues.jboss.org/browse/JBTM/fixforversion/12329358/?selectedTab=com.atlassian.jira.plugins.jira-development-integration-plugin:release-report-tabpanel
This release of Narayana was integrated into the WildFly application server as commit https://github.com/wildfly/wildfly/commit/f91666c2b46617229dd041e512488a379c83f16f under https://issues.jboss.org/browse/WFLY-6092. This means it will be in WildFly 10.1.0.Final (based on that projects currently allocated fixVersion in Jira).

5.2.12.Final Released

Its also worthwhile mentioning that 5.2.12.Final was released as part of WildFly 10 Final which is great too. That work can be seen via https://issues.jboss.org/browse/WFLY-5938.
The release notes for that version can be seen over here:
https://issues.jboss.org/browse/JBTM/fixforversion/12329351/?selectedTab=com.atlassian.jira.plugins.jira-development-integration-plugin:release-report-tabpanel

Upcoming work and requests for feedback

We are currently working on integration with various other frameworks. We could really do with some help understanding what features would be most beneficial to you. The areas we are looking at in particular are Spring, Camel and Karaf but we would be happy to discuss those or almost anything transaction related over on our forum:
Users: https://developer.jboss.org/en/jbosstm/content?filterID=contentstatus%5bpublished%5d~objecttype~objecttype%5bthread%5dImplementers: https://developer.jboss.org/en/jbosstm/dev/content?filterID=contentstatus%5bpublished%5d~objecttype~objecttype%5bthread%5d

Performance

Alongside the usual selection of enhancements and bug fixes we have been working on sharing performance figures comparing ourselves against a selection of other projects available in the open source community with a view to checking that the release remains competitive. We haven't been particularly been working on performance enhancements, rather the development of a microbenchmark of 2PC that is fair and consistent in our environment - you will almost certainly see different numbers in your particular environment based on the spec of your machine etc but we would expect the general ranking to be consistent. The tool we have found works for us is called JMH (a micro benchmark harness created by the OpenJDK project team available from http://openjdk.java.net/projects/code-tools/jmh/).

We have attempted to configure each product on an equal footing by choosing sensible defaults for each tunable parameter and by ensuring that recovery is enabled, although we do configure Narayana with the journal store, which is our best performing transaction log storage mechanism. If you have any recommendations for other transaction managers or how to tune the configuration then please let us know so that we can update our test job.

The benchmark runs a transaction containing two dummy resources.

We will let the figures speak for themselves, suffice to say that when more and more threads are thrown at the workload we scale better showing that we have excellent control over parallelism.

The graph for this run is:

Monday, December 28, 2015

Software Transactional Memory with WildFly-Swarm

A long time ago (not in a Galaxy Far Far Away!) I wrote about the STM implementation we were adding to Narayana. Over the intervening years this implementation was added to Vert.x and even the RaspberryPi made an appearance! Now whilst the implementation has been available in WildFly for many years, we tend not to mention it because, well, it's not Java EE compliant. However, with the advent of WildFly-Swarm things may be about to change.

Sure, when you're looking at using Swarm it's likely that at least initially you'll be coming at a problem from the perspective of Java EE, but the more you look to decompose your application into constituent (micro) services the more chances there are that you'll also start to look at functionality and frameworks that aren't necessarily just about Java EE. As we've mentioned before, STM is compatible with JTA and JTS transactions as well, as long as you understand what it means to mix-and-match them. Therefore, we've added an example of STM usage within WildFly-Swarm, which hopefully will become part of the mainline Swarm examples eventually. Take a look and give us any feedback, either in the Swarm group/IRC/Twitter or the usual Narayana routes.

Wednesday, September 30, 2015

JTS Docker Container

So last week our new Docker image became available on https://hub.docker.com. It is a standalone JTS service running the premiere open source transaction manager written by the Narayana team.
In addition to that, it comes with a helper image - JacORB name server, which provides an easy way of sharing the transaction managers IOR.
The transaction manager image can be found here:
And the JacORB name server image can be found here:

Usage

This image comes with a quickstart example available on Narayana Github page: https://github.com/jbosstm/quickstart/tree/master/jts-docker. But here I’ll provide a brief extract from the quickstart to explain how the JTS Docker image can be used.
We use Docker linking technology to make interaction between JTS and JacORB containers more smooth. Thus JTS container expects certain environments to be available. Not to worry though, they are automatically created by Docker.
Here is how to start the name server container:
docker run -p 3528:3528 -it --name jacorb-name-server jboss/jacorb-name-server
And this is how to start JTS container on Linux, linking it with the name server:
docker run -p 4711:4711 -it --link jacorb-name-server:jacorb-name-server --name jts-transaction-service jboss/jts-transaction-service
Or if you're running on Boot2Docker start JTS container as follows:
docker run -p 4711:4711 -it -e "PROXY_IP={Boot2Docker IP}" --link jacorb-name-server:jacorb-name-server --name jts-transaction-service jboss/jts-transaction-service
And that is it. Now you can connect to the name server from your application and retrieve the IOR of the transaction manager. Pretty easy.
Of course, since Docker container storage is removed once the container is removed, this is not the best way to use any transaction manager as you will want to make sure your transactions are completed even in case of the system failure. To avoid such scenarios and make the transaction log reliable you have two options: mount a host directory or use JDBC object store.
But you can read more about that in our quickstart readme:
Additionally, in the quickstart you’ll find an example of how to coordinate JacORB name server and JTS transaction service containers with Kubernetes.

Thursday, September 10, 2015

Updating multiple one-phase resources with Narayana

I was recently forwarded a link to an article regarding the use of Springs chained-transaction manager facility wherein the author had utilised this facility to coordinate updates to multiple one-phase resources. This gave me the opportunity to show-case a Narayana facility which has existed for many years that allows you to build something with similar a similar purpose and possibly richer properties.
What we will create is an application that uses multiple one-phase resources (for example, some hypothetical none-XA database and message queue). We will use Narayanas AbstractRecord extension mechanism to order the commit messages to the resource managers in any way that would be appropriate for the application. We will then take a look at some options for failure recovery options.

Notes:

  • Applications of this style (i.e. multiple 1PC) are only suited for certain classes of applications. Where possible it is almost always preferable to use 2PC resources to provide spec-compliant transactional outcomes.
  • The code I am going to use to demonstrate some of this is derived from a unit test in our repository but I will extract some of the code to below. I won't actually use resource managers in this example to try to illustrate the pattern as clearly as possible.
  • If the test ever moves around, you can probably track it via its SHA 8e9f712d5b89762c7b841cf370eb5bdb341fff4d.

Transactional business logic

The general layout of the application follows the same pattern of any other transactional application:
        // Get references to resource managers
        ResourceManager1 rm1 = ...;
        ResourceManager2 rm2 = ...;

        // Create a transaction
        AtomicAction A = new AtomicAction();
        A.begin();

        // Enlist resource manager in transaction
        A.add(new OrderedAbstractRecord(rm1));
        A.add(new OrderedAbstractRecord(rm2));

        // Do business logic
        // rm1.sendMessage()
        // rm2.doSQL()

        // Commit the transaction, the order will be defined in OrderedAbstractRecord rather than
        // the business logic or AtomicAction::add() order
        A.commit();

Guaranteeing the order of commit messages

The ordering of the list for transaction completion events is dictated by the RecordList class. At the most fundamental level, for AbstractRecords of the same type it is determined by the Uid returned in the AbstractRecords order method. As Uids are sequentially numbered at some level, this basically means that if you return a Uid lower to a peer, your record instance will be committed before that one.
So for example, the order of Uid you allocate to the following class will determine the order AbstractRecord::topLevelCommit() is called:

public class OrderedOnePhaseAbstractRecord extends AbstractRecord {
    public OrderedOnePhaseAbstractRecord(Uid uid)
    {
        super(uid);
        order = uid;
    }
    public Uid order()
    {
        return order;
    }
    //...
}

Failure tolerance properties

A final observation to make is that by using the Narayana AbstractRecord facility, it allows you to know that in the presence of a failure, during crash recovery you will receive callback where it may even be possible to re-do some of the work in the later resources.
For example, in the AbstractRecords save_state you could save some of the content of the JMS message which can then be used in a possible recovery scenario to resend a similar message.

Thursday, August 6, 2015

Narayana 5.2.1.Final released!

The whole team is proud to announce the latest release of our project, version numbered 5.2.1.Final :)

This was primarily a bug fix release within which however we also polished off a couple of house keeping tasks including moving our dependency on the HornetQ journal to the Artemis journal, plus a new facility to auto-launch an embedded recovery manager when starting the transaction service standalone.  The complete release notes are available from here.

Wildfly has had our upgrade merged in so you should see a nightly build of WildFly that includes the upgrade available soon over here.

Saturday, May 16, 2015

XA and microservices

I had a very interesting series of discussions this week with a few friends/colleagues about whether or not transactions are applicable in a microservices architecture. I've already covered these points in an earlier entry so I won't repeat them here. However, several things did come up that are worthy of trying to address, including the assumption that they're too hard to use and too hard to test your application for correctness when using them. Now as I've mentioned in several presentations there are valid concerns like these around using or not using transactions in general, i.e., irrespective of microservices.

These points that came up recently are not just to be dismissed out of hand. Having worked in transactions for almost 30 years I've spent a long time hearing about these and other concerns and trying to address them within our industry with many others from a range of companies. For instance, if you look at what we've achieved within Java EE with CDI annotations for transactions, or within Narayana for similar approaches towards compensations, I think we've come a long way to simplifying how developers can use transactions. The STM work that we've done is also another example of putting transactions into the hands of developers and not requiring them to have to worry even about demarcation or state management.

Testing applications and their use of transactions is obviously important, in just the same way as when adding any component or capability, such as Hibernate, Zookeeper or Map/Reduce. However, once again we've made a lot of progress over the years. Within Narayana we have 1000s of unit and QA tests which not only help to prove the correctness of the underlying implementation but also feed into best practices etc. for developers. Then there's transaction extensions to Arquillian which also help to make testing much easier. Now in terms of proving the correctness of transaction systems we're also pretty safe there (no pun intended). Since transactions have been used in mission critical environments for over five decades there's a large body of associated work to prove the various aspects are correct for implementations and applications. Overall I'm fairly sure that these concerns have been addressed sufficiently well to not be a meaningful reason to avoid transactions, in general or with microservices. As an industry could we do better? Of course. We should always be striving to improve the overall developer experience and how transactions fit in.

However, one other thing which did come up during the conversations I referred to initially is that there's often a concern that transactions equals XA, or put another way, that the problems perceived to be present with transactions are the result of design issues inherent within the original XA protocol and associated implementations. As I keep saying, 2PC and transactions existed before XA and many transaction system implementations aren't tied to only supporting the XA protocol. All of the transaction standards have their quirks, just as most standards do no matter their domain. But XA has a few more than its fair share, often due to the fact it's been around for so long that the ways in which we tend to develop applications have changed radically since it was defined. Yet we're tied to it due to the fact that relational databases still represent the majority way in which we store data. Of course we've developed new transaction standards which don't rely upon XA, such as OTS or WS-AT, but most developers still see and use XA and hence why there may be concerns about transactions which are really more to do with XA.

Back to the topic: I'm not suggesting that XA doesn't have a role to play within microservices and between microservices. At least in the short term it most definitely does for some (small) set of applications. But really when I'm suggesting transactions have a role I'm looking well beyond XA. I'm still considering ACID as well as compensation transactions though because as I've said, some implementations aren't tied to XA and yet provide the optimisations you expect from XA (one-phase commit, read-only optimisation) as well as going beyond (interposition, nested transactions). So whilst I definitely understand concerns about transactions, I still believe they either have been addressed and we need to do a better job of developer education, or we can address them; the benefits they bring are worth it.

Thursday, May 7, 2015

Application servers are dead. Apparently.

OK so you may be wondering what the title has to do with transactions. Well it's really because of this article I came across recently. It's slightly old and I'm not sure how I missed it the first time round (maybe I had better things to do at the time!) Anyway, I'm not going to argue about whether or not application servers are dead: you can find enough from me on that topic by searching on JBoss.org or elsewhere.

What I did want to focus on was the transactions references in the article. Basically the author looks at some of the capabilities that an application server provides and tries to show how the same things can be done outside of an application server or with other frameworks/stacks. Well you can probably guess how the comments on transactions went down with me! Let's start by deconstructing the paragraph - yes, it only deserved a paragraph on something I think is so fundamental to enterprise applications! But hey, maybe I'm just strange (don't go there!)

"2PC is used to coordinate multiple transaction resource that should take part in a single transaction. Whether this feature makes sense could be the subject of an article in its own right. " Now of course you could interpret the last sentence in a number of ways, but I'll give the author the benefit of the doubt. Yes, transactions aren't always the right thing to use and in some cases they've definitely been misused.

Then we have: "If 2PC is used to coordinate two databases the architecture might be wrong. Why is data distributed across two databases if it has such a close relation that it should be changed as part of a single transaction?" Erm, exsqueeze me?! Have you heard of separation of concerns? Or maybe different organisations? Or perhaps difference companies? Or what about different levels of security/encryption, so a company stores and updates data in different repositories/data stores with different levels? And of course there's that other example ... replication!

The next bit made be laugh and then cry: "If JMS and access to a database are done in the same transaction synchronization might be an alternative. It offers almost the same guarantees but is a lot less complex and resource consuming." I can almost imagine the conversation: "Yes sir, we lost your money transfer because the message got lost but we were assured the chances of it happening were so small we really didn't need transactions and could use something that was almost exactly the same thing!" Look, a Citroen Belingo is almost the same thing as a Ferrari but I know which one I'd prefer!

"And remember: Also 2 PC can fail – like any IT system." Yes, it can fail. But guess what? A good transaction system implementation will have something called crash recovery (or failure recovery) which will attempt to resolve things for you automatically so you, the developer or sys admin, don't have to. Catastrophic failures may be unrecoverable, but then that would be the case without transactions anyway.

Then it wraps up with: "In modern Systems that use technologies such as REST or NoSQL 2PC cannot be used anyway. These technologies do not support 2PC. So more often than not 2PC is not that useful." OK so what about things like REST Transactions (the clue's in the name!) and the work we've been doing on compensation transactions and NoSQL?

Look, in general the recommendation(s) to stay away from transactions is bogus and ill-informed. If you don't want to use an application server that doesn't mean you should throw away everything that you get from it such as transactions. For instance, you don't need to use Narayana in the scope of an application server - in fact it began life years before there was ever such a thing!