📄 ch03.html
字号:
<TD ROWSPAN="1" COLSPAN="1"><P CLASS="TB"><A NAME="pgfId-1087609"></A><EM CLASS="CODE">TX_REQUIRED_NEW</EM><A NAME="marker-1087608"></A> </P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="2"><P CLASS="TB"><A NAME="pgfId-1087611"></A>Container-managed transaction. The server starts and manages a new transaction. If an existing transaction starts this transaction, it suspends until this transaction completes.</P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="1"><P CLASS="TB1"><A NAME="pgfId-1087619"></A>Specified as bean transaction-type in deployment descriptor.</P></TD><TD ROWSPAN="1" COLSPAN="1"><P CLASS="TB1"><A NAME="pgfId-1087622"></A><EM CLASS="CODE">TX_BEAN_MANAGED</EM><A NAME="marker-1087621"></A> </P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="2"><P CLASS="TB"><A NAME="pgfId-1087624"></A>Bean-managed transaction. You access the transaction context to begin, commit, or roll back the transaction as needed.</P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="1"><P CLASS="TB"><A NAME="pgfId-1087629"></A><EM CLASS="CODE">SUPPORTS</EM><A NAME="marker-1087628"></A></P></TD><TD ROWSPAN="1" COLSPAN="1"><P CLASS="TB"><A NAME="pgfId-1087632"></A><EM CLASS="CODE">TX_SUPPORTS</EM><A NAME="marker-1087631"></A> </P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="2"><P CLASS="TB"><A NAME="pgfId-1087634"></A>If the code calling this bean has a transaction running, include this bean in that transaction.</P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="1"><P CLASS="TB"><A NAME="pgfId-1087639"></A><EM CLASS="CODE">NEVER</EM><A NAME="marker-1087638"></A></P></TD><TD ROWSPAN="1" COLSPAN="1"><P CLASS="TB"><A NAME="pgfId-1087642"></A><EM CLASS="CODE">TX_NOT_SUPPORTED</EM><A NAME="marker-1087641"></A> </P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="2"><P CLASS="TB"><A NAME="pgfId-1087644"></A>If the code calling a method in this bean has a transaction running, suspend that transaction until the method called in this bean completes. No transaction context is created for this bean. </P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="1"><P CLASS="TB"><A NAME="pgfId-1087649"></A><EM CLASS="CODE">MANDATORY</EM><A NAME="marker-1087648"></A></P></TD><TD ROWSPAN="1" COLSPAN="1"><P CLASS="TB"><A NAME="pgfId-1087652"></A><EM CLASS="CODE">TX_MANDATORY</EM><A NAME="marker-1087651"></A></P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="2"><P CLASS="TB-rule"><A NAME="pgfId-1087654"></A>The transaction attribute for this bean is set when another bean calls one of its methods. In this case, this bean gets the transaction attribute of the calling bean. If the calling bean has no transaction attribute, the method called in this bean throws a <EM CLASS="CODE">TransactionRequired</EM> exception.</P></TD></TR></TABLE><P CLASS="Body"><A NAME="pgfId-1087660"></A><EM CLASS="Bold">Isolation-Level Descriptions. </EM><A NAME="marker-1087658"></A><A NAME="marker-1087659"></A>An enterprise bean uses an <EM CLASS="EM">isolation level</EM> to negotiate its own interaction with shared data, and to negotiate the interaction of other threads with the same shared data. As the name implies, there are various levels of isolation with <EM CLASS="CODE">TRANSACTION_SERIALIZABLE</EM> providing the highest level of data integrity. </P><UL><P CLASS="NOTE"><A NAME="pgfId-1087661"></A>NOTE Be sure to verify that your database can handle the level you choose. In the Enterprise JavaBeans 1.1 specification, only bean-managed session beans can set the isolation level. If the database cannot handle the isolation level, the Enterprise JavaBeans server will get a failure when it tries to call the <EM CLASS="CODE">setTransactionIsolation</EM> JDBC method. </P></UL><P CLASS="Body"><A NAME="pgfId-1087663"></A><EM CLASS="C-Code">TRANSACTION_SERIALIZABLE. </EM><A NAME="marker-1087662"></A>This level provides maximum data integrity. The bean gets what amounts to exclusive access to the data. No other transaction can read or write this data until the serializable transaction completes.</P><P CLASS="Body"><A NAME="pgfId-1087664"></A>In this context, serializable means to <EM CLASS="EM">process the data as a serial operation</EM>; it should not be confused with serializing objects to preserve and restore their states. Running transactions as a single serial operation is the slowest setting. If performance is an issue, use another isolation level that meets your application requirements but provides better performance. </P><P CLASS="Body"><A NAME="pgfId-1087666"></A><EM CLASS="C-Code">TRANSACTION_REPEATABLE_READ. </EM><A NAME="marker-1087665"></A>At this level, data read by a transaction can be read, but not modified, by another transaction. The data is guaranteed to have the same value it had when first read, unless the previous transaction changes it and writes the changed value back. </P><P CLASS="Body"><A NAME="pgfId-1087668"></A><EM CLASS="C-Code">TRANSACTION_READ_COMMITTED. </EM><A NAME="marker-1087667"></A>At this level, data read by a transaction cannot be read by other transactions until the previous transaction either commits or rolls back. However, if another transaction alters the data after this transaction starts, a second read would retrieve the modified data. To prevent this type of inconsistent data, use <EM CLASS="CODE">TRANSACTION_REPEATABLE_READ</EM>.</P><P CLASS="Body"><A NAME="pgfId-1087670"></A><EM CLASS="C-Code">TRANSACTION_READ_UNCOMMITTED. </EM><A NAME="marker-1087669"></A>At this level, data involved in a transaction can be read by other threads before the previous transaction either completes or rolls back. The other transactions cannot tell whether the data was finally committed or rolled back. </P><P CLASS="Body"><A NAME="pgfId-1087672"></A><EM CLASS="Bold">Bean-Managed Example. </EM><EM CLASS="CODE">SellerBean</EM> is a session bean that uses <EM CLASS="CODE">RegistrationBean</EM> and <EM CLASS="CODE">AuctionItemBean</EM> in the following ways:</P><UL><LI CLASS="BL"><A NAME="pgfId-1087673"></A><EM CLASS="CODE">RegistrationBean</EM> checks the user ID and password when someone posts an auction item, and debits the seller's account for a listing.</LI><LI CLASS="BL"><A NAME="pgfId-1087674"></A><EM CLASS="CODE">AuctionItemBean</EM> adds new auction items to the database. </LI></UL><P CLASS="Body"><A NAME="pgfId-1087676"></A>The transaction begins in the <EM CLASS="CODE">SellerBean.insertItem</EM> method with the account debit and ends when the entire transaction either commits or rolls back. The entire transaction including the 50-cents debit rolls back if the auction item is null (the insertion failed) or if an exception is caught. If the auction item is not null and the insertion succeeds, the entire transaction including the 50-cents debit commits. </P><P CLASS="Body"><A NAME="pgfId-1087677"></A>For this example, the isolation level is <EM CLASS="CODE">TRANSACTION_SERIALIZABLE</EM>, and the transaction attribute is <EM CLASS="CODE">TX_BEAN_MANAGED</EM>. The other beans in the transaction, <EM CLASS="CODE">RegistrationBean</EM> and <EM CLASS="CODE">AuctionItemBean</EM>, have an isolation level of <EM CLASS="CODE">TRANSACTION_SERIALIZABLE</EM> and a transaction attribute of <EM CLASS="CODE">REQUIRED</EM>. Changes to this version of <EM CLASS="CODE">SellerBean.insertItem</EM> over the container-managed version are flagged with comments. </P><PRE CLASS="CODE"><A NAME="pgfId-1087678"></A>public int insertItem(String seller, String password, String description, int auctiondays, double startprice, String summary) throws RemoteException {//Declare transaction context variable using the//javax.transaction.UserTransaction class UserTransaction uts= null; try { Context ectx = new InitialContext(p);//Get the transaction context uts=(UserTransaction)ctx.getUserTransaction(); RegistrationHome rhome = (RegistrationHome)ectx.lookup("registration"); RegistrationPK rpk=new RegistrationPK(); rpk.theuser=seller; Registration newseller=rhome.findByPrimaryKey(rpk); if((newseller == null)|| (!newseller.verifyPassword(password))) { return(Auction.INVALID_USER); }//Start the transaction</PRE><PRE CLASS="CODE-caption"><A NAME="pgfId-1087680"></A>//API Ref: <A NAME="46283"></A>void begin()</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087685"></A> <A NAME="marker-1087681"></A> <A NAME="javax.jts.UserTransaction class"></A><A NAME="UserTransaction class"></A><A NAME="begin method"></A>uts.begin(); //Deduct 50 cents from seller's account newseller.adjustAccount(-0.50); AuctionItemHome home = (AuctionItemHome) ectx.lookup("auctionitems"); AuctionItem ai= home.create(seller, description, auctiondays, startprice, summary); if(ai == null) {//Roll transaction back</PRE><PRE CLASS="CODE-caption"><A NAME="pgfId-1087687"></A>//API Ref: <A NAME="46783"></A>void rollback()</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087690"></A> <A NAME="marker-1087688"></A> <A NAME="rollback method"></A>uts.rollback(); return Auction.INVALID_ITEM; } else {//Commit transaction </PRE><PRE CLASS="CODE-caption"><A NAME="pgfId-1087692"></A>//API Ref: <A NAME="98946"></A>void commit()</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087695"></A> <A NAME="marker-1087693"></A> <A NAME="commit method"></A>uts.commit(); return(ai.getId()); } } catch(Exception e){ System.out.println("insert problem="+e);//Roll transaction back if insert fails uts.rollback(); return Auction.INVALID_ITEM; }}</PRE></DIV></DIV><DIV><H4 CLASS="A"><A NAME="pgfId-1087697"></A><A NAME="74089"></A>Bean-Managed Finder Methods</H4><P CLASS="Body"><A NAME="pgfId-1087700"></A><A NAME="marker-1087698"></A><A NAME="marker-1087699"></A>The container-managed search described in Chapter 2, Auction House Application, is based on a finder-method mechanism in which the deployment descriptor, rather than the bean, specifies the finder-method behavior. While the finder mechanism works well for simple queries and searches, it cannot handle complex operations that span more than one bean type or database table. Also, the Enterprise JavaBeans 1.1 specification currently provides no specification for putting finder rules in the deployment descriptor. </P><P CLASS="Body"><A NAME="pgfId-1087702"></A><A NAME="marker-1087701"></A>So, for more complex queries and searches, you have to write bean-managed queries and searches. This section explains how to write a bean-managed version of the auction house search facility of Chapter 2. The bean-managed search involves changes to the <EM CLASS="CODE">AuctionServlet.searchItems</EM> method and a new session bean, <EM CLASS="CODE">SearchBean</EM>. </P><DIV><H5 CLASS="B"><A NAME="pgfId-1087703"></A><EM CLASS="B-code">AuctionServlet.searchItems</EM></H5><P CLASS="Body"><A NAME="pgfId-1087705"></A><A NAME="marker-1087704"></A>The search begins when the end user submits a search string to the search facility on the auction house home page and clicks the Submit button. This invokes <EM CLASS="CODE">AuctionServlet</EM>, which retrieves the search string from the HTTP header and passes it to the <EM CLASS="CODE">searchItem</EM> method. </P><UL><P CLASS="NOTE"><A NAME="pgfId-1087706"></A>NOTE The search logic for this example is fairly simple. The idea here is to show you how to move the search logic into a separate enterprise bean so you can create a more complex search on your own. </P></UL><P CLASS="Body"><A NAME="pgfId-1087707"></A>Figure 3.1 shows how the <EM CLASS="CODE">searchItem</EM> operation is in the following two parts: (1) Using the search string to retrieve primary keys, and (2) Using <A NAME="marker-1087708"></A>primary keys to retrieve auction items. Parts 1 and 2 are described in more detail below the figure. </P><DIV><H6 CLASS="FC"><A NAME="pgfId-1087713"></A>Figure 3.1 <A NAME="60018"></A>Search items operation</H6><DIV><IMG SRC="CH03-1.gif"></DIV><P CLASS="Body"><A NAME="pgfId-1087714"></A>Part 1: The first thing the <EM CLASS="CODE">searchItems</EM> method does is pass the search string submitted by the end user to the <EM CLASS="CODE">SearchBean</EM> session bean. <EM CLASS="CODE">SearchBean</EM> implements a bean-managed search that retrieves a list of primary keys for all auction items whose <EM CLASS="CODE">Summary</EM> fields contain characters matching the search string. This list is returned to the <EM CLASS="CODE">searchItems</EM> method in an <EM CLASS="CODE">Enumeration</EM> variable. </P><PRE CLASS="CODE"><A NAME="pgfId-1087717"></A><A NAME="marker-1087715"></A><A NAME="marker-1087716"></A>private void searchItems(ServletOutputStream out, HttpServletRequest request)</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087718"></A> throws IOException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087719"></A> String searchString=request.getParameter("searchString");</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087720"></A> String text = "Click Item number for description and to place bid.";</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087721"></A> setTitle(out, "Search Results");</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087722"></A> try {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087723"></A> addLine("<BR>"+text, out);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087724"></A>//Look up Home interfaces</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087725"></A> AuctionItemHome ahome = (</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087726"></A> AuctionItemHome) ctx.lookup("auctionitems");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -