📄 lib0090.html
字号:
<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Transaction Management</title>
<link rel="STYLESHEET" type="text/css" href="images/xpolecat.css">
<link rel="STYLESHEET" type="text/css" href="images/ie.content.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/teamlib.gif" width="62" height="15" border="0" align="absmiddle" alt="Team LiB"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href="LiB0089.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0091.html"><img src="images/next.gif" width="41" height="15" border="0" align="absmiddle" alt="Next Section"></a>
</div></td></tr></table>
<br>
<div class="chapter">
<a name="ch13"></a>
<div class="section">
<h2 class="first-section-title"><a name="434"></a><a name="ch13lev1sec1"></a>Transaction Management</h2><p class="first-para">For J2EE applications, you can manage transactions differently than you do for other types of Java applications. Some texts refer to transaction management as transaction demarcation. The J2EE specification defines the Java <a name="435"></a><a name="IDX-177"></a>Transaction API (JTA), which provides a standard interface for transaction management. This standard interface allows container vendors to provide features such as two-phase commit capability.</p>
<p class="para">J2EE developers typically have the choice of managing transactions programmatically via JTA or instructing the container (via enterprise bean deployment descriptors) to perform transaction management automatically. Many of my clients manage transactions programmatically, opting not to use JTA features and locally managing their transactions using JDBC. Programmed transaction management enables the business logic layer to function outside a J2EE environment.</p>
<p class="para">Because of the variety of methods for managing transactions in J2EE applications, most texts advocate putting business logic in enterprise beans. They recommend this so you can take advantage of container transaction management features. Although I agree with the desire to offer advanced features, I respectfully disagree with the practice of making the business logic layer deployment specific.</p>
<p class="para">
<b class="bold">Decouple transaction management tasks from the business logic layer with</b> <b class="bold">an interface.</b> By decoupling transaction management, you can keep the business logic layer locally debuggable but still make advanced transaction management features available for J2EE deployments. An example of this concept is interface <span class="fixed">TransactionContext</span> (from package <span class="fixed">org.cementj.base.trans</span>), defined within CementJ.</p>
<p class="para">
<span class="fixed">TransactionContext</span> is a part of CementJ, not a native part of the JDK or J2EE specification. If you prefer not to use CementJ directly, you can take this discussion as a "concept" example and still apply the concepts to the business logic layer. You would, of course, have to invent your own version of <span class="fixed">TransactionContext</span>.</p>
<p class="para">
<span class="fixed">TransactionContext</span>, as implemented in CementJ, is a transaction manager that provides database connections, begins transactions, and manages commits and rollbacks. Because <span class="fixed">TransactionContext</span> is an interface, the implementation can be J2EE specific (i.e., use JTA) for J2EE deployments but use native JDBC for other types of environments. Either way, the business logic is identical in all environments.</p>
<p class="para">
<a class="internaljump" href="#ch13list01">Listing 13.1</a> contains the definition for <span class="fixed">TransactionContext</span>.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 13.1: </span>Defining TransactionContext</span><a name="436"></a><a name="ch13list01"></a>
<div class="formalbody">
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="Start example" border="0"></b></font></td>
</tr>
</table>
<pre class="literallayout">
1:package org.cementj.base.trans;
2:<a name="437"></a><a name="IDX-178"></a>
3:import java.sql.Connection;
4:
5:public interface TransactionContext
6:{
7:
8: public Connection getConnection(String label)
9: throws TransactionException;
10:
11: public void commitAll() throws TransactionException;
12:
13: public void rollbackAll()
14: throws TransactionException;
15:
16: public void begin() throws TransactionException;
17:
18: public void closeAll() throws TransactionException;
19:}
</pre>
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="End example" border="0"></b></font></td>
</tr>
</table>
<table class="BlankSpace" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td height="16"></td>
</tr>
</table>
</div>
</div>
<p class="para">Let's look at each method in detail. <span class="fixed">TransactionContext</span> provides all database connections needed by the data access layer in the method <span class="fixed">getConnection()</span>. Many applications use multiple database connections to different sources. For this reason, a "label" to identify the connection type is required. In a J2EE context, this will typically be your database pool name.</p>
<p class="para">
<span class="fixed">TransactionContext</span> provides the ability to demark transaction beginnings using the method <span class="fixed">begin()</span>. In a J2EE application, JTA usually performs this task. <span class="fixed">TransactionContext</span> also provides a way to commit or roll back transactions using <span class="fixed">commitAll()</span> and <span class="fixed">rollbackAll()</span>, respectively.</p>
<p class="para">
<span class="fixed">TransactionContext</span> enables you to close all opened connections via <span class="fixed">closeAll()</span>. You should close all opened connections to prevent connection leaks, which we will discuss later.</p>
<p class="para">It is imperative that you don't issue commits, rollbacks, or closes on the connections obtained from <span class="fixed">TransactionContext</span> directly. Doing so will make your transactions "local" and circumvent the use of container transaction management features. <a class="internaljump" href="#ch13list02">Listing 13.2</a> illustrates the use of <span class="fixed">TransactionContext</span>.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 13.2: </span>Using TransactionContext to Decouple Transaction Management</span><a name="438"></a><a name="ch13list02"></a>
<div class="formalbody">
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="Start example" border="0"></b></font></td>
</tr>
</table>
<pre class="literallayout">
1:package book.sample.bo;
2:
3:import book.sample.vo.PurchaseOrderVO;
4:import book.sample.dao.db.PurchaseOrderDAO;<a name="439"></a><a name="IDX-179"></a>
5:// some code omitted
6:
7:public class PurchaseOrder
8: extends BusinessLogicObject
9:{
10:
11: // some code omitted
12:
13: public void record()
14: throws InsufficientCreditException,
15: InternalApplicationException
16: {
17: if (_purchaseOrderVO == null)
18: throw new IllegalArgumentException(
19: "Null orders not allowed.");
20:
21: try
22: {
23: this._transactionContext.begin();
24: Connection conn =
25: this._transactionContext.getConnection(
26: "MyDbPoolName");
27: CreditValidationBO creditBO =
28: new CreditValidationBO(
29: this._transactionContext);
30: double availableCredit =
31: creditBO.getAvailableCredit(
32: _purchaseOrderVO.getCustomerId());
33:
34: if ( _purchaseOrderVO.getTotalOrderAmount() >
35: availableCredit)
36: {
37: throw new InsufficientCreditException
38: ( "Sorry — your order exceeds your available" +
39: " credit of $" + availableCredit + "!");
40: }
41:
42: PurchaseOrderDAO orderDAO =
43: new PurchaseOrderDAO(conn);
44: orderDAO.savePurchaseOrder(_purchaseOrderVO);
45: this._transactionContext.commitAll();
46: }
47: catch (InsufficientCreditException i)
48: {
49: this._transactionContext.rollbackAll();
50: throw i;
51: }
52: catch (InternalApplicationException iae)
53: {<a name="440"></a><a name="IDX-180"></a>
54: this._transactionContext.rollbackAll();
55: throw iae;
56: }
57: catch (Throwable t)
58: {
59: this._transactionContext.rollbackAll();
60: throw new InternalApplicationException
61: ( "Error recording PO ==> " +
62: _purchaseOrderVO.describe(), t);
63: }
64: finally {this._transactionContext.closeAll();}
65: }
66:}
</pre>
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="End example" border="0"></b></font></td>
</tr>
</table>
<table class="BlankSpace" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td height="16"></td>
</tr>
</table>
</div>
</div>
<p class="last-para">
<i class="emphasis">Source:</i> /src/book/sample/bo/PurchaseOrder.java</p>
</div>
</div><br>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/teamlib.gif" width="62" height="15" border="0" align="absmiddle" alt="Team LiB"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href="LiB0089.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0091.html"><img src="images/next.gif" width="41" height="15" border="0" align="absmiddle" alt="Next Section"></a>
</div></td></tr></table>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -