| By Frances Zhao, Paul Parkinson | Article Rating: |
|
| July 22, 2007 07:45 PM EDT | Reads: |
22,713 |
Let's take a step-by-step look at our sample trading application showing how Spring can be used when an external transaction manager is required.
Let's use the Oracle Application Server transaction manager as an example that demonstrates the integration of JTA with Spring's OC4JJtaTransactionManager. The application demonstrates the classic distributed two-phase commit transaction use case requiring ACID properties: the bank account transfer. Funds are debited from one account and credited to another. Either both the debit and credit must occur or neither must occur. In this example, the transfer is from a bank account to a brokerage account to purchase individual stocks. The example includes a very simple MVC-style application consisting of a test controller, financial service, asset management service, and two data access objects representing a bank and a brokerage. Container-manager transactions are used. The example adds additional aspects to this scenario to demonstrate the extended features of the OC4JJtaTransactionManager that include named transactions and per-transaction isolation-level designation.
The following HowToJTASpringController implements the Spring Controller and InitializingBean interfaces. Note that the setFinancial method provides the FinancialService implementation (as specified in applicationContext.xml).
public class HowToJTASpringController implements InitializingBean,
Controller {
private FinancialService m_financial;
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
FinancialReport financialReport = m_financial.processFinancials();
request.setAttribute("financialReport", financialReport);
return new ModelAndView("/jsp/success.jsp");
}
catch (Exception e) {
request.setAttribute("error", e.getMessage());
return new ModelAndView("/jsp/error.jsp");
}
}
The FinancialServiceImpl class implements the Spring InitializingBean interface as well as the FinancialService interface. The setAssetManagement method is called by the Spring Framework, which also provides the AssetManagementService implementation (as specified in applicationContext.xml) using dependency injection. The Transactional class-level annotation (transaction annotation support is specified in applicationContext.xml) designates that business methods of this class, namely processFinancials, have a propagation value of REQUIRED. That is, the methods execute in a transaction if one exists or a transaction is started if none exists. The annotation also specifies that the transaction is to be readOnly and that the isolation level of any connections used in the transaction are set to SERIALIZABLE.
@Transactional(readOnly = true, propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE)
public class FinancialServiceImpl implements InitializingBean, FinancialService {
AssetManagementService m_assetManagementService;
public FinancialReport processFinancials() {
AssetReport assetReportBeforeStockPurchase = m_assetManagementService.
reportAllAssets();
StockPurchaseReport stockPurchaseReport = m_assetManagementService.
purchaseNewStockAndReport();
AssetReport assetReportAfterStockPurchase = m_assetManagementService.
reportAllAssets();
return new FinancialReport(assetReportBeforeStockPurchase, stockPur
chaseReport, assetReportAfterStockPurchase);
}
public final void afterPropertiesSet() throws Exception {
if (m_assetManagementService == null)
throw new BeanCreationException("NoAssetManagementService was set. Verify context xml.");
}
public void setAssetManagement(AssetManagementService assetManagementService) {
m_assetManagementService = assetManagementService;
}
}
The AssetManagementServiceImpl class implements the Spring InitializingBean interface as well as the AssetManagementService interface. The setBank and setBrokerage methods are called by the Spring Framework providing the Bank and Brokerage DAO implementations (as specified in applicationContext.xml) using dependency injection.
The Transactional method-level annotation (transaction annotation support is specified in applicationContext.xml) designates that the purchaseNewStockAndReport method has a propagation value of REQUIRED. That is, it executes in a transaction if one exists, or a transaction is started if none exists. The annotation also specifies the isolation-level of any connections used in the transaction be set to READ_COMMITTED.
Another method-level Transactional annotation designates that the reportAllAssets method has a propagation value of SUPPORTS. That method executes in a transaction if one exists but doesn't throw an exception or start a transaction if none exists. The annotation also specifies that the noRollbackFor be set to ConcurrencyFailureException.class, which indicates that if a transaction exists and this Spring DAO RuntimeException is thrown, the transaction shouldn't rollback as a result.
public class AssetManagementServiceImpl implements InitializingBean, AssetManagementService {
private Bank m_bank;
private Brokerage m_brokerage;
@Transactional(propagation = Propagation.SUPPORTS, noRollbackFor = ConcurrencyFailureException.class)
public AssetReport reportAllAssets() {
return new AssetReport(m_bank.selectBalance(), m_brokerage.selectAllStocks());
}
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
public StockPurchaseReport purchaseNewStockAndReport() {
int stockAmount = 10;
String stockSymbol = "ABC";
m_bank.updateBalance(m_bank.selectBalanceForUpdate() - stockAmount);
m_brokerage.insertStock(stockSymbol, stockAmount);
return new StockPurchaseReport(stockSymbol, stockAmount);
}
public final void afterPropertiesSet() throws Exception {
if (m_bank == null) throw new BeanCreationException("No Bank was set. Verify context xml.");
if (m_brokerage == null) throw new BeanCreationException("No Brokerage was set. Verify context xml.");
}
public void setBank(Bank bank) {
m_bank = bank;
}
public void setBrokerage(Brokerage brokerage) {
m_brokerage = brokerage;
}
}
Published July 22, 2007 Reads 22,713
Copyright © 2007 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Frances Zhao
Frances Zhao is a principal product manager in the Oracle Fusion Middleware team. Her focus is on the core J2EE container.
More Stories By Paul Parkinson
Paul Parkinson has been working with and developing transaction processing technology for 15 years. His work at Oracle includes the development of the Java Transaction API and Java Transaction Service implementations in the OC4J application server as well as performance and high-availability features, Web Service Transactions, and transactional aspects of JCA.
![]() |
Guy Pardon 07/24/07 08:58:32 AM EDT | |||
(Trying again - link not property showing in my first post) A complete working JMS/JDBC application with Spring JTA integration can be found here: http://www.onjava.com/pub/a/onjava/2006/02/08/j2ee-without-application-s... |
||||
![]() |
Guy Pardon 07/24/07 08:56:16 AM EDT | |||
Nice article, though the sample application seems a bit exotic (2 databases are being combined in a synchronous, tighly-coupled integration scenario). More common is a loosely-coupled architecture where you have one (JMS) queue and one database - banks are also more likely to work that way. A complete working JMS/JDBC application with Spring JTA integration can be found here: www.onjava.com/pub/a/onjava/2006/02/08/j2ee-without-application-server.html more (and in-depth) info on Spring's transaction configuration options is in following presentation: http://media.techtarget.com/tss/BeJUG/J2EEAppsSpring/player.html Disclaimer: I should mention that I am the author of both these publications, and heavily involved in some of the related technologies. Best |
||||
- 4th International Cloud Computing Conference & Expo Starts Today
- Publishing Synergy: Blog, Twitter and Ulitzer
- Performance Tuning Essentials for Java
- Cloud Expo New York Call for Papers Deadline December 15
- Google Wave
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- Cloud Computing Can Revitalize Your Career as Software Developer
- SOA World Magazine "Readers' Choice Awards" Voting Is Now Open
- Oracle+MySQL Opponents Take to the Barricades
- Virtualization Expo Call for Papers Deadline December 15
- Oracle Faces Growing Price for MySQL
- SpringSource Moving to Spring 3.0
- 4th International Cloud Computing Conference & Expo Starts Today
- Deputy CIO of the CIA to Keynote 1st Annual GovIT Expo
- Publishing Synergy: Blog, Twitter and Ulitzer
- Performance Tuning Essentials for Java
- Cloud Expo New York Call for Papers Deadline December 15
- Cloud Computing Expo: Exclusive Q&A with Yahoo! SVP Cloud Computing
- Google Wave
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- Cloud Computing Can Revitalize Your Career as Software Developer
- Oracle-Sun: IBM Reportedly Behind Delay
- Citrix Aims To Cripple VMware’s Cloud Designs
- Oracle Trashes HP Relationship for Sun
- After Ubuntu, Windows Looks Increasingly Bad, Increasingly Archaic, Increasingly Unfriendly
- SCO CEO Posts Open Letter to the Open Source Community
- Simula Labs Launches Hosted Delivery Platform To Enable Enterprise Open Source Adoption
- Where Are RIA Technologies Headed in 2008?
- Source Claims SCO Will Sue Google
- How Open Is "Open"? – Industry Luminaries Join the Debate
- Latest SCO News is Plain Weird
- IBM Tells SCO Court It Can't Find AIX-on-Power Code
- SCO Claims Linux Lifted ELF
- Flashback: Investing in 'Professional Open Source' - Exclusive 2004 Interview with David Skok, Matrix Partners
- HP Starts Pushing Desktop Linux
- Linux Business Week Exclusive: Linux Kernel To Be Re-Written To Counter Microsoft FUD






























