注意,本实验要求完成《配置Data Source(2)》。
有时我们需要在程序中编码自己控制事务,在WebLogic Server中,你可以在JNDI Tree中找到UserTransaction对象。
使用UserTransaction对象,你可以编程管理全局事务。
1. 两个账户之间转账的例子
基本逻辑如下:首先看看要转出的账户余额是否足够,然后把转出的账户-金额,转入的账户+金额。
整个逻辑要求在一个事务中完成,要么全部成功,否则全部回滚。
package com.servlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.naming.*;
import javax.transaction.*;
import java.sql.*;
import javax.sql.*;
public class transfer extends HttpServlet
{
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.setContentType("text/html");
ServletOutputStream out = response.getOutputStream();
String name = request.getParameter("employee");
int id = getID(name);
String action = request.getParameter("Xfer");
boolean flag = false;
String amt = request.getParameter("amount");
if ((amt.equals("")) || (action == null))
{
out.print("You need to fill out the form in its entirety");
}
else {
int amount = Integer.valueOf(amt).intValue();
UserTransaction tran = null;
Connection connection = null;
Statement statement = null;
ResultSet rs = null;
try
{
tran = startTransaction();
connection = getConnection();
statement = connection.createStatement();
String sql = "SELECT * FROM EMPLOYEE WHERE ID=" + id;
rs = statement.executeQuery(sql);
rs.next();
int plan = rs.getInt("PLAN");
int savings = rs.getInt("SAVINGS");
if (action.equals("savingsto401"))
{
if (amount > savings)
flag = true;
else
{
savings -= amount;
plan += amount;
}
}
else {
if (amount > plan)
flag = true;
else
{
savings += amount;
plan -= amount;
}
}
if (flag)
{
out.print("<FONT SIZE='4' COLOR='navy'>");
out.print("Insufficient Funds<BR>");
out.print("Transaction Has Been Rolled Back <BR>");
out.print("</FONT>");
tran.rollback();
}
else
{
sql = "UPDATE EMPLOYEE SET PLAN=" + plan + " WHERE ID=" + id;
statement.executeUpdate(sql);
sql = "UPDATE EMPLOYEE SET SAVINGS=" + savings + " WHERE ID=" + id;
statement.executeUpdate(sql);
out.print("<FONT SIZE='4' COLOR='navy'>");
out.print(amount + " was transferred <BR>");
out.print("Current balances are:<BR>");
out.print(" 401K plan: " + plan + " <BR>");
out.print(" Savings: " + savings + " <BR>");
out.print("</FONT>");
tran.commit();
}
} catch (Exception e) {
try
{
tran.rollback();
} catch (Exception exception) {
out.print("Rollback Exception: " + exception);
}
out.print("General exception: " + e);
}
finally {
try {
if ( rs != null ) {
rs.close();
rs = null;
}
if ( statement != null ) {
statement.close();
statement = null;
}
if (connection != null) {
connection.close();
connection = null;
}
} catch (SQLException sqle) {}
}
out.print("<BR><A HREF='./moneymanagement.jsp'>Back To The Money Management Page</A><BR>");
}
}
public UserTransaction startTransaction()
{
try
{
InitialContext ic = new InitialContext();
UserTransaction tran = (UserTransaction) ic.lookup("javax.transaction.UserTransaction");
tran.begin();
return tran;
} catch (Exception e) {
System.out.println("Error occurred begining transaction: " + e);
}
return null;
}
public int getID(String name)
{
int index = name.indexOf(" ");
String sub = name.substring(0, index);
int id = Integer.valueOf(sub).intValue();
return id;
}
public Connection getConnection()
{
try
{
InitialContext ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup("dizzyworldDS");
Connection conn = ds.getConnection();
return conn;
} catch (Exception e) {
System.out.println("Error occurred getting connection to DB with data source 'dizzyworldDS' " + e);
}
return null;
}
}
2. 访问应用:http://localhost:7003/retirement/
3. 在Console中监控JTA:总共有多少个事务?多少个提交了?多少个回退了?
[domain_name]->Environment->Servers,点击[server_name],点击Monitoring,选择JTA Tab
Project下载:retirement.war
没有评论:
发表评论