Message-ID: <1187736626.4333.1369440506542.JavaMail.email@example.com> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_4332_1644938066.1369440505996" ------=_Part_4332_1644938066.1369440505996 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
Why is the JTA API your friend ? How does it help you write better code = ? Those are questions that we will try to answer here. These best practices= are not limited to BTM but are valid for all JTA implementations. The more= you use JTA, the better the world will be.
Even if you're only planning to use a single database in your applicatio= n (ie: if you don't plan to make use of 2 Phase Commit) using the JTA API i= s still a good idea as it helps separating concerns in your application.
The biggest benefit is the separation of the transaction management conc= ern from the connection management concern. What does that mean ?
When using 'good old' JDBC, you work with a single object type: the
SELECT, INSERT, UPDATE, DELETE) and for transaction mana=
COMMIT and ROLLBACK).
This is awkward as you often end up using an object for a concern (data = manipulation) then keep it aside for later usage for another concern (commi= tting or rolling back your changes).
Take this simple example to illustrate our concern:
This code is reasonably clean as the calling business method (
uteA_B_C()) does no know that the underlying logic is using JDBC whi=
ch is good Object Oriented design. It is also possible to encapsulate the J=
DBC boilerplate code in some helper class, DAO or even delegate that to a m=
ore powerful solution like Spring's JdbcTemplate. Data access code will change in that case but =
the idea stays the same.
Unfortunately the data manipulation is not atomic: if an error happen in=
executeBusinessLogicB then all modifications made by
ecuteBusinessLogicA cannot be rolled back.
A commonly found way to fix this problem is by sharing the
ion object between all 3 business methods:
The code is now much less clean as to ensure all 3 business methods will=
execute in the same transaction, we pass them a
ject which is not of any business value.
How to get the clean data access encapsulation of Example 1 together wit=
h correct transaction handling of the Example 2 ? A straightforward continu=
ation of the same logic could lead us to some kind of
r singleton that would store the connection in a
code> variable. The different business methods would then get their
onnection from the
While this would work, this is not as trivial as it sounds. You would ha=
ve to initialize the
ConnectionHolder (or make it initialize l=
azily) then clean up all resources it holds together with exception handlin=
g. This also makes the code less reusable as you always need to ensure you =
have access to a
ConnectionHolder from within your business me=
A better solution is to separate the transaction management logic from t= he data access logic, and this is exactly what JTA is for.
Not only is this code more maintainable than the previous example 2 but = it also improves example one in two areas: not only is it now fully transac= tional but the error handling is now centralized.
You don't have to care about connections, just get them from the pool wh= en needed and release them as soon as you're done with it. The transaction = manager and the connection pool will ensure the transaction will be committ= ed at the right time.
As long as you're sticking with a single database, you won't pay the ext=
ra 2PC costs as the 1PC optimization will kick in. You don't even need a da=
XADataSource thanks to the Last Resource Commit implementation.
JTA not only allows you to cleanly separate our concerns, it also comes = with extra benefits: