2009年3月5日星期四

WLS_012:WebLogic Server基本管理之八:使用UserTransaction编程管理全局事务

运行环境:WebLogic Server 10.3.5 + Oracle Database 10g Express Edition 10.2.0.1。
注意,本实验要求完成《配置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

没有评论: