The Component Implementation Code Comparison

Gopalan Suresh Raj

Implementing the Server Component

MTS server component- All the classes that are required for Java/COM are defined in the com.ms.com package. The com.ms.mtx package contains all the MTS related class definitions. The com.ms.wfc.data package contains all the ADO related class definitions. The MTS Server object shown below implements the IChecking interface that we defined in our IDL file. Implementation code for the different methods like createAccount(), credit(), debit(), getBalance() and getCustomerName() are also shown.

In MTS, the developer implements the business methods, but doesn't have to implement any callback methods. The developer must code transaction commit and rollback demarcation statements. If everything goes right, the developer must call SetComplete() on the transaction context object. If anything goes wrong, the developer must call SetAbort() on the transaction context object. MTS supports four automatic transaction semantics which may de assigned declaratively. MTS does not support manual transactions.

EJB server component- All the classes that are required for Java/RMI are defined in the java.rmi package. The javax.ejb package contains all the EJB related class definitions. The java.sql package contains all the JDBC related class definitions. The EJB Server object shown below implements the SessionBean interface since its a session bean. Implementation code for the different methods like createAccount(), credit(), debit(), getBalance() and getCustomerName() are also shown.

In EJB, the transaction semantics for an enterprise bean are defined declaratively rather than programmatically. At runtime, the EJB container automatically implements transaction services according to the TransactionAttribute specified in the deployment descriptor. In EJB, the developer must define the remote interface, and the developer must implement the business methods and the EJB callback methods (although in many cases they can be left empty). The EJB container deployment tools automatically generate the EJB wrapper objects.

MTS - Component implementation code

EJB - enterprise Bean implementation Code
package bank;

import com.ms.com.*;
import com.ms.com.IUnknown;
import com.ms.mtx.*;
import com.ms.wfc.data.*;

package Bank;

import java.rmi.*;
import javax.ejb.*;
import java.util.*;
import java.sql.*;

/** @com.register(clsid=6B6EBD42-01C0-11D3-97EE-006097A7D34F,
 * typelib=6B6EBD40-01C0-11D3-97EE-006097A7D34F, version="1.0")
 * @com.transaction (required)
 */
 ////////////////////////////////////////////////////////////////
//          Class Definition
 ////////////////////////////////////////////////////////////////
public class CheckingImpl implements IUnknown,
 com.ms.com.NoAutoScripting, bank.ICheckingDefault {
 ////////////////////////////////////////////////////////////////
 static final int ALL_FIELDS   = 0;
 static final int NAME_FIELD   = 1;
 static final int BALANCE_FIELD= 2;
 
 
//odbc type connection string
 static final String m_strOpenConn =
 "PROVIDER=Microsoft.Jet.OLEDB.3.51;"+

"Data Source=E:\\MyProjects\\AccountMTS\\BankServer\\Bank.mdb";
//////////////////////////////////////////////////////////////////
//          Class Definition
//////////////////////////////////////////////////////////////////
public class CheckingBean implements SessionBean {
//////////////////////////////////////////////////////////////////
 
 protected SessionContext _sessionContext;
 
 static final int ALL_FIELDS   = 0;
 static final int NAME_FIELD   = 1;
 static final int BALANCE_FIELD= 2;


 //////////////////////////////////////////////////////////////////
 //          Home Interface methods
 //////////////////////////////////////////////////////////////////
  
public void ejbCreate () {
  }
  ////////////////////////////////////////////////////////////////
 //          Business methods
 ////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////
 public void createAccount (int key, String name,
                                       double startingBalance) {
 ////////////////////////////////////////////////////////////////
  if (startingBalance < 0)
   return;
 
  boolean bSuccess = false;
 
  IObjectContext context = null;
  try {
  
// Get the Object Context
   context = (IObjectContext)MTx.GetObjectContext ();
   truePut (CheckingImpl.ALL_FIELDS, key,
            (new Double (startingBalance)).toString (), name);

   bSuccess = true;
  }
  catch (Exception e) {
   bSuccess = false;
   e.printStackTrace ();
  }
  // Upon exit, always call SetComplete () if happy,
  // or SetAbort () if unhappy
  // We do this since we never save state across method calls.
 
finally {
   if (context!=null) {
    if (bSuccess == true)
     context.SetComplete ();
    else
     context.SetAbort ();
   }
  }
 }
 //////////////////////////////////////////////////////////////////
 //          Remote Interface methods
 //////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////
 public void createAccount (int key, String name,
                                       double startingBalance)
{

 //////////////////////////////////////////////////////////////////
  if (startingBalance > 0) {
   truePut (CheckingBean.ALL_FIELDS, key,
            startingBalance, name);

  }
 }
  ////////////////////////////////////////////////////////////////
 public void credit (double amount, int key) {
  ////////////////////////////////////////////////////////////////
 
  double balance = 0.0;
  boolean bSuccess = false;
 
  try {
   balance = getBalance (key);
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
 
  System.out.println("changing Checkings::balance from " + balance);

   // Get the Object Context
  IObjectContext context = (IObjectContext)MTx.GetObjectContext ();
 
  try {
   if( amount > 0 ) {
    balance += amount;
    truePut (CheckingImpl.BALANCE_FIELD, key,
             (new Double(balance)).toString (), "");

    bSuccess = true;
   }
  }
  catch (Exception e) {
   bSuccess = false;
   e.printStackTrace ();
  }
  // Upon exit, always call SetComplete () if happy,
  // or SetAbort () if unhappy
  // We do this since we never save state across method calls.
  finally {
   if (context!=null) {
    if (bSuccess == true)
     context.SetComplete ();
    else
     context.SetAbort ();
   }
  }
  System.out.println (" to " + balance);
 }

 ////////////////////////////////////////////////////////////////
 public void credit (double amount, int key) {    ////////////////////////////////////////////////////////////////

  double balance = 0.0;
 
  try {
   balance = this.getBalance (key);
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
 
  System.out.println ("changing Checking::balance from " + balance);

  try {
   if( amount > 0 ) {
    balance += amount;
    truePut (CheckingBean.BALANCE_FIELD, key,
             balance, "");

   }
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
  System.out.println (" to " + balance);
 }

  ////////////////////////////////////////////////////////////////
 public void debit (double amount, int key) {
  ////////////////////////////////////////////////////////////////
  double balance = 0.0;
  boolean bSuccess = false;
 
  try {
   balance = getBalance (key);
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
 
  System.out.println ("changing Checkings::balance from " + balance);

    // Get the Object Context
  IObjectContext context = (IObjectContext)MTx.GetObjectContext ();
 
  try {
   if ( (amount > 0) && (balance >= amount) ) {
    balance -= amount;
    truePut (CheckingImpl.BALANCE_FIELD, key,
             (new Double (balance)).toString (), "");

    bSuccess = true;
   }
  }
  catch (Exception e) {
   bSuccess = false;
   e.printStackTrace ();
  }
  // Upon exit, always call SetComplete () if happy,
  // or SetAbort () if unhappy
  // We do this since we never save state across method calls.
  finally {
   if (context!=null) {
    if (bSuccess == true)
     context.SetComplete ();
    else
     context.SetAbort ();
   }
  }
  System.out.println (" to " + balance);
 }

 ////////////////////////////////////////////////////////////////
 public void debit (double amount, int key) {
 ////////////////////////////////////////////////////////////////
  double balance = 0.0;
 
  try {
   balance = getBalance (key);
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
  System.out.println("changing CheckingBean::balance from " + balance);
 
  try {
   if ( (amount > 0) && (balance >= amount) ) {
    balance -= amount;
    truePut (CheckingBean.BALANCE_FIELD, key,
             balance, "");

   }
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
  System.out.println(" to " + balance);
 }

  ////////////////////////////////////////////////////////////////
 public double getBalance (int key) {
  ////////////////////////////////////////////////////////////////
 
  double  balance = 0.0;
  boolean bSuccess= false;
  System.out.println ("Invoking Checkings::getBalance");
  IObjectContext context = null;
 
  try {
  
// Get the Object Context
   context = (IObjectContext)MTx.GetObjectContext ();
 
   String result = trueGet (CheckingImpl.BALANCE_FIELD, key);
   balance = (new Double (result)).doubleValue();
   bSuccess = true;
  }
  catch (Exception e) {
   bSuccess = false;
   e.printStackTrace ();
  }
 
  // Upon exit, always call SetComplete () if happy,
  // or SetAbort () if unhappy
  // We do this since we never save state across method calls.
finally {
   if (context!=null) {
    if (bSuccess == true)
     context.SetComplete ();
    else
     context.SetAbort ();
   }
  }
 
  System.out.println ("Checkings::balance is " + balance);
  return balance;
 }
 ////////////////////////////////////////////////////////////////
 public double getBalance (int key) {
 ////////////////////////////////////////////////////////////////
 
double  balance = 0.0;

  try {
 
   String result = trueGet (CheckingBean.BALANCE_FIELD, key);
   balance = (new Double (result)).doubleValue();
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
 
  System.out.println("CheckingBean::balance is " + balance);
  return balance;
 }

  ////////////////////////////////////////////////////////////////
 public String getCustomerName (int key) {
  ////////////////////////////////////////////////////////////////
 
  String  name = null;
  boolean bSuccess= false;
  System.out.println ("Invoking Checkings::getCustomerName");
 
  IObjectContext context = null;
 
  try {
  
// Get the Object Context
   context = (IObjectContext)MTx.GetObjectContext ();
   name = trueGet (CheckingImpl.NAME_FIELD, key);
   bSuccess = true;
  }
  catch (Exception e) {
   bSuccess = false;
   e.printStackTrace ();
  }
 
  // Upon exit, always call SetComplete () if happy,
  // or SetAbort () if unhappy
  // We do this since we never save state across method calls.
finally {
   if (context!=null) {
    if (bSuccess == true)
     context.SetComplete ();
    else
     context.SetAbort ();
   }
  }
 
  System.out.println ("Checkings::customer_name is " + name);
  return name;
 }
 ////////////////////////////////////////////////////////////////
 public String getCustomerName (int key) {
 
////////////////////////////////////////////////////////////////
 
  String  name = null;
  boolean bSuccess= false;
 
  try {
   name = trueGet (CheckingBean.NAME_FIELD, key);
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
 
  System.out.println ("Checking::customer_name is " + name);
  return name;
 }
  ////////////////////////////////////////////////////////////////
 //          Other Internal methods
  ////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////
 String trueGet (int type, int key) {
  ////////////////////////////////////////////////////////////////
  Connection connection = null;
  Recordset  rset = null;
  Variant    rowCount = new Variant ();
  String     result = null;
  String     query = null;
  String     fieldName = null;
 
  switch (type) {
   case CheckingImpl.NAME_FIELD:
    query =
"SELECT CUSTOMER_NAME FROM Checkings WHERE ACCOUNT_NUMBER=";
    fieldName = "CUSTOMER_NAME";
    break;

   case CheckingImpl.BALANCE_FIELD:
    query =
    "SELECT BALANCE FROM Checkings WHERE ACCOUNT_NUMBER=";
    fieldName = "BALANCE";
    break;
  }
 
  try {
   //STEP1 : open the connection
   connection = new Connection ();
   connection.open (CheckingImpl.m_strOpenConn);
   query += key;
 
   //STEP 2: Obtain the desired recordset with a query
   rset = connection.execute (query);
 
   //STEP 3:Get the appropriate fields
   if (!rset.getEOF()) {
    result = rset.getField (fieldName).getString ();
   }
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
  finally {
  
// Cleanup that needs to occur whether we leave via a return or exception
   if (rset != null) {
    if (rset.getState () == AdoEnums.ObjectState.OPEN)
     rset.close ();
    ComLib.release (rset);
    rset = null;
   }
 
   if (connection != null) {
    if (connection.getState () == AdoEnums.ObjectState.OPEN)
     connection.close ();
    ComLib.release (connection);
    connection = null;
   }
  }
  return result;
 }

 ////////////////////////////////////////////////////////////////
 //          Other Internal methods
 ////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////
 String trueGet (int type, int key) {
 ////////////////////////////////////////////////////////////////
  Connection connection = null;
  PreparedStatement stmt= null;
  ResultSet  rset = null;
  String     result = null;
  String     query = null;
  String     fieldName = null;
 
  switch (type) {
   case CheckingBean.NAME_FIELD:
    query =
        "SELECT CUSTOMER_NAME FROM Checkings "+
        "WHERE ACCOUNT_NUMBER = ?";
    fieldName = "CUSTOMER_NAME";
    break;

   case CheckingBean.BALANCE_FIELD:
    query =
    "SELECT BALANCE FROM Checkings WHERE ACCOUNT_NUMBER = ?";
    fieldName = "BALANCE";
    break;
  }
 
  try {
  
//STEP1 : open the connection
   connection = this.getConnection ();
   stmt = connection.prepareStatement (query);
   stmt.setInt (1, key);
 
  
//STEP 2: Obtain the desired resultset with a query
   rset = stmt.executeQuery ();
 
  
//STEP 3:Get the appropriate fields
   if (!rset.wasNull ()) {
    rset.next ();
    result = rset.getString (fieldName);
   }
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
  finally {
  
// Cleanup that needs to occur whether we leave via
  
// a return or exception
   try {
    if (stmt != null) {
     stmt.close ();
     stmt = null;
    }
    if (connection != null) {
     connection.close ();
     connection = null;
    }
   }
   catch (Exception e) {
    e.printStackTrace ();
   }
  }
  return result;
 }

  ////////////////////////////////////////////////////////////////
 String truePut (int type, int key, String balance,
                       String name)
{
  ////////////////////////////////////////////////////////////////
  Connection connection = null;
  Recordset  rset = null;
  Variant    rowCount = new Variant ();
  String     result = null;
  String     query = null;
 
  switch (type) {
   case CheckingImpl.BALANCE_FIELD:
    query = "UPDATE Checkings SET BALANCE=" + balance +
            " WHERE ACCOUNT_NUMBER="+ key;
    break;

   case CheckingImpl.NAME_FIELD:
   case CheckingImpl.ALL_FIELDS:
   default:
    query = "INSERT INTO Checkings VALUES ( '"+ key
            +"','"+ name +"','"+balance+"')";
    break;
  }
 
  try {
   //STEP1 : open the connection
   connection = new Connection ();
   connection.open (CheckingImpl.m_strOpenConn);
 
   //STEP 2: Execute the query
   connection.execute (query);
 
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
  finally {
  
// Cleanup that needs to occur whether we leave via a return or exception
   if (rset != null) {
    if (rset.getState () == AdoEnums.ObjectState.OPEN)
     rset.close ();
    ComLib.release (rset);
    rset = null;
   }
 
   if (connection != null) {
    if (connection.getState () == AdoEnums.ObjectState.OPEN)
     connection.close ();
    ComLib.release (connection);
    connection = null;
   }
  }
  return result;
 }

}

 ////////////////////////////////////////////////////////////////
 String truePut (int type, int key, double balance,
                 String name)
{
 
////////////////////////////////////////////////////////////////
  Connection connection = null;
  PreparedStatement stmt= null;
  ResultSet  rset = null;
  String     result = null;
  String     query = null;
 
  switch (type) {
   case CheckingBean.BALANCE_FIELD:
    query = "UPDATE Checkings SET BALANCE = ? "+
                 "WHERE ACCOUNT_NUMBER = ?";
    break;

   case CheckingBean.NAME_FIELD:
   case CheckingBean.ALL_FIELDS:
   default:
    query = "INSERT INTO Checkings VALUES ( ?, ?, ? )";
    break;
  }
 
  try {
   //STEP1 : open the connection
   connection = this.getConnection ();
   stmt = connection.prepareStatement (query);
   if (type == CheckingBean.BALANCE_FIELD) {
    stmt.setDouble (1, balance);
    stmt.setInt (2, key);
   }
   else {
    stmt.setInt (1, key);
    stmt.setString (2, name);
    stmt.setDouble (3, balance);
   }
 
   //STEP 2: Execute the query
   rset = stmt.executeQuery ();
   rset.next ();
 
  }
  catch (Exception e) {
   e.printStackTrace ();
  }
  finally {
  
// Cleanup that needs to occur whether we leave via
  
// a return or exception
   try {
    if (stmt != null) {
     stmt.close ();
     stmt = null;
    }
    if (connection != null) {
     connection.close ();
     connection = null;
    }
   }
   catch (Exception e) {
    e.printStackTrace ();
   }
  }
  return result;
 }

   ////////////////////////////////////////////////////////////////
 public Connection getConnection () throws Exception {
 ////////////////////////////////////////////////////////////////
  return DriverManager.getConnection ("jdbc:odbc:Bank");
 }

   ////////////////////////////////////////////////////////////////
 public CheckingBean () {
 ////////////////////////////////////////////////////////////////
 }

 ////////////////////////////////////////////////////////////////
 //       Mandatory callback methods required by the EJB Spec
 ////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////
 public void ejbActivate () {
 ////////////////////////////////////////////////////////////////
 }

 ////////////////////////////////////////////////////////////////
 public void ejbPassivate () {
 ////////////////////////////////////////////////////////////////
 }

 ////////////////////////////////////////////////////////////////
 public void ejbRemove () {
 ////////////////////////////////////////////////////////////////
 }

 ////////////////////////////////////////////////////////////////
 public void setSessionContext (SessionContext context)
   throws RemoteException {
 ////////////////////////////////////////////////////////////////
  this._sessionContext = context;
 }

}

CheckingImpl.java

CheckingBean.java

 

Back to EJB vs MTS

click here to go to
My Advanced Java / J2EE Tutorial HomePage...

click here to go to
My COM+ / DNA Tutorial HomePage...

click here to go to
My CORBA Tutorial HomePage...


Go to the Component Engineering Cornucopia page

This site was developed and is maintained by Gopalan Suresh Raj

This page has been visited times since May 04,1999.

Last Updated : May 04,'99

If you have any questions, comments, or problems regarding this site, please write to me I would love to hear from you.


Copyright (c) 1997-2000, Gopalan Suresh Raj - All rights reserved. Terms of use.

All products and companies mentioned at this site are trademarks of their respective owners.