Transactions: Are You in Control?

The launch of BEA's WebLogic Platform 8.1 was greeted with enthusiasm by industry analysts and IT practitioners alike, who recognized its potential to open up the power of the J2EE platform to a much broader spectrum of developers. This allowed J2EE architects to do what their skills are best suited for - architectural design and technical problem solving - while allowing the architectures designed by the experts to be used by the "ordinary" developers, who hitherto had been restricted to building departmental-scale applications because of the lack of an architecture for scalability underpinning the applications they produced with the "more accessible" tools they were accustomed to using.

Two key features of the WebLogic Platform enable this separation of duties between the high-level business developers and the highly technical J2EE architects - the BEA WebLogic Workshop runtime, which imposes some high-level architectural order on the high-level business developers; and the Workshop development environment, which allows the developers to interact with the environment via a consistent graphical abstraction, turning to lines of code only when they need to express some business rule, not when they try to assemble an application. The IDE also has a feature to help the architects - they can produce a skeletal application environment, populated with standard components, etc., and release that to the other developers as a template, getting the business programmers off to a flying start (and importantly, a flying start consistent with development standards and other development projects) in a pre packaged and automated way.

The key part of the runtime framework is the Controls architecture - controls provide a consistent way to encapsulate business logic. Business developers can code their business rules and provide them as components using controls, or to encapsulate complex logic and infrastructure needed to access some resource. J2EE architects can implement this "hard-core plumbing" and wrap it in a control that can then be used just as easily by the app developers as a piece of their own logic. This solves another problem that large development shops usually have - the J2EE coders produce lots of really excellent infrastructure, but it can only be consumed by other J2EE experts, because business developers don't understand how to use it.

Overall, from the J2EE developer perspective they get to avoid doing lots of dull, error-prone cut-and-pasting - let's face it, just another struts form front end, or just another code excerpt to look up a JMS queue in JNDI and send a message on it is nobody's favorite pastime. From the non-J2EE developer perspective, the assembly of a useful application from preexisting components (i.e., building another set of Web screens that combine existing subsystems in new ways) becomes possible without having to burn the midnight oil learning the J2EE incantations.

Transactions: Have You Lost the Plot?
So what on earth does that have to do with transactions? Well, nothing, it's just background. Without covering that, how can I write the article I wanted to? And what is that? Well...

Transactions, Workshop, and Controls
Controls are simply annotated Java objects - and it is these annotations that provide the magic that allows control users to work at a level of abstraction above the usual J2EE interface. When a control (which may actually be a composite of multiple controls) is deployed, the annotations drive the generation of the right runtime linkage (which is what is actually deployed). Like any other Java object, controls inherit their transactional context from the caller. Since controls have no concept of a remote interface (at least not in the current release), the caller is always a lightweight control container generated by WebLogic Workshop, which is itself contained by an EJB. If you look at the deployment descriptor associated with this (Workshop-managed) EJB, you will see that it has a transaction policy of "container" - so the transactional context of the controls will be provided by the EJB container, using JTA, just as if the control were a plain old Java object that you wrote and invoked from EJB code.

The nearest thing to a remote interface in Workshop is a Web service - it is very easy to take a control and expose it as a Web service (potentially, and a conversational Web service) with no more than a few mouse clicks, so the remaining question becomes...

What Is the Default Transactional Behavior of a Workshop Web Service?
Each time a call comes in to a Web service method, the linkage from message arrival to invocation has been done through a number of bits of J2EE machinery (depending on exactly what you have declared in the annotations), culminating in an EJB with conatiner-managed transactions. For the duration of the execution of the method, a JTA transaction will be in operation. If the method succeeds, the transaction commits. If the method fails (throws an Exception) the transaction will be rolled back. Easy so far.

Recall, though, that a WebLogic Workshop Web service can be conversational (again, if the annotations say it is). The conversation state is persisted in a database table. How does this persistent state relate to any application-managed persistent state? Well, it is included in the same transaction context. So if your method fails, it is as if that leg of the conversation never happened - the kind of nice, atomic behavior transactions are loved for. This has some implications on the deployment - by default, the conversation state is persisted via a data source called cgDataSource. If your application state is persisted elsewhere, you will get an error saying you can't infect your data source with the transaction because it already infects the cgPool underlying the cgDataSource. You can fix this in two ways: either change cgPool to use xa database access and get a two-phase commit, or have both the conversation state and your application state held in the same database instance via the same connection pool (Workshop's jws-config.properties file controls this from the Workshop perspective) and avoid the need for a two-phase commit.

If a Workshop Web service calls another Web service, the transaction context will not be propagated so the called service will run in its own new transaction according to the rules I just outlined. If you would like the failure of a service call to roll back the caller's transaction, rethrow the exception to the framework. If you want the caller's state (both application and conversational) to be persisted in spite of a Web service call failure, catch the exception and don't re-throw it.

Of course, the usual rules about transactions apply. If you want something (say an audit record) persisted irrespective of the transaction's eventual outcome, then you need to get the TransactionManager object and suspend the transaction before making the call and resume it afterwards. This is getting hairy for a non-J2EE guru type, which makes it exactly the kind of thing the J2EE architects should implement and provide to the application developers as a pre-built Control.

The Key Is, It Doesn't Matter!
So the last few hundred words were all a bit rocket-science like (or at least, a bit close to rocket-science like) for many application developers. Well, that's the point. If the J2EE architects understand this stuff, and bear it in mind when they put together templates and development guidelines for the app developers, then the app developers shouldn't need to worry about it - the framework will do the right thing on their behalf, and they will produce more applications more quickly whose behavior will be more consistent than they could have hoped for without the framework and the templates steering them in the right direction. All of which might even mean an IT department that can smile and say yes the next time the business changes the requirements again at the last minute, rather than muttering something about dilithium crystals and updating its résumé!

References

  • John Methot's white paper on BEA WebLogic Workshop internals: http://dev2dev.bea.com/products/wlworkshop81/articles/wlw_internals.jsp. This covers the runtime implementation of the Workshop framework, and how it can be configured to behave differently in more detail than there is space for here.
  • © 2008 SYS-CON Media