WebSphere Application Server, Version 6.1   
             オペレーティング・システム: AIX , HP-UX, Linux, Solaris, Windows, Windows Vista

             目次と検索結果のパーソナライズ化

例: CMP Bean と BMP Bean 間の接続を共用するための IBM 拡張 API の使用

JDBC オブジェクト (Bean 管理パーシスタンス (BMP) Bean) を 介してデータにアクセスするアプリケーション・コンポーネント内で、接続を取得する前に、WebSphere 拡張 API を使用し、オブジ ェクトを介して接続プロパティーを定義することができます。この性質により、BMP Bean が コンテナー 管理パーシスタンス (CMP) Bean と接続を共用する可能性が高まります。

トランザクション内の他のコンテナー管理パーシスタンス (CMP) Bean と 共用できる共用可能接続を用いて、BMP Bean を実行する場合、WebSphere Application Server 拡張 API を使用して接続を取得するように お勧めします。 この API を使用すると、 アプリケーションを他のアプリケーション・サーバーに移植できません。

この場合、DataSource インターフェースではなく、拡張 API WSDataSource インターフェースを使用してください。CMP Bean と Bean 管理パーシスタンス (BMP) Bean の両方が同じ物理接続を必ず共用するために、両者において 同じアクセス・インテント・プロファイルを定義してください。BMP メソッド内部で、 リレーショナル・リソース・アダプターの helper クラスから、適切な分離レベルを取得できます。

package fvt.example;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.ejb.CreateException;
import javax.ejb.DuplicateKeyException;
import javax.ejb.EJBException;
import javax.ejb.ObjectNotFoundException;
import javax.sql.DataSource;

// following imports are used by the IBM extended API
import com.ibm.websphere.appprofile.accessintent.AccessIntent;
import com.ibm.websphere.appprofile.accessintent.AccessIntentService;
import com.ibm.websphere.rsadapter.JDBCConnectionSpec;
import com.ibm.websphere.rsadapter.WSCallHelper;
import com.ibm.websphere.rsadapter.WSDataSource;
import com.ibm.websphere.rsadapter.WSRRAFactory;

/**
 * Bean implementation class for Enterprise Bean: Simple
 */

public class SimpleBean implements javax.ejb.EntityBean {
 private javax.ejb.EntityContext myEntityCtx;

 // Initial context used for lookup.

 private javax.naming.InitialContext ic = null;

 // define a JDBCConnectionSpec as instance variable

 private JDBCConnectionSpec connSpec;

 // define an AccessIntentService which is used to get
 // an AccessIntent object.

 private AccessIntentService aiService;

 // AccessIntent object used to get Isolation level

 private AccessIntent intent = null;
 
 // Persitence table name

 private String tableName = "cmtest";

 // DataSource JNDI name

 private String dsName = "java:comp/env/jdbc/SimpleDS";

 // DataSource

 private DataSource ds = null;

 // bean instance variables.

 private int id;
 private String name;

 /**
  * In setEntityContext method, you need to get the AccessIntentService
  * object in order for the subsequent methods to get the AccessIntent
  * object.
  * Other ejb methods will call the private getConnection() to get the
  * connection which has all specific connection properties
  */

 public void setEntityContext(javax.ejb.EntityContext ctx) {
  myEntityCtx = ctx;

  try {
   aiService =
    (AccessIntentService) getInitialContext().lookup(
     "java:comp/websphere/AppProfile/AccessIntentService");
   ds = (DataSource) getInitialContext().lookup(dsName);
  }
  catch (javax.naming.NamingException ne) {
   throw new javax.ejb.EJBException(
    "Naming exception: " + ne.getMessage());
  }
 }

  /**
  * ejbCreate
  */

 public fvt.example.SimpleKey ejbCreate(int newID)
  throws javax.ejb.CreateException, javax.ejb.EJBException {
  Connection conn  = null;
  PreparedStatement ps = null;

  // Insert SQL String

  String sql = "INSERT INTO " + tableName + " (id, name) VALUES (?, ?)";

  id = newID;
  name = "";

  try {
                    // call the common method to get the specific connection

   conn = getConnection();
  }
  catch (java.sql.SQLException sqle) {
   throw new EJBException("SQLException caught: " + sqle.getMessage());
  }
  catch (javax.resource.ResourceException re) {
   throw new EJBException(
    "ResourceException caught: " + re.getMessage());
  }

  try {
   ps = conn.prepareStatement(sql);			
   ps.setInt(1, id);
   ps.setString(2, name);

   if (ps.executeUpdate() != 1){
    throw new CreateException("Failed to add a row to the DB");
   }
  }
  catch (DuplicateKeyException dke) {
   throw new javax.ejb.DuplicateKeyException(
    id + "has already existed");
  }
  catch (SQLException sqle) {
   throw new javax.ejb.CreateException(sqle.getMessage());
  }
  catch (CreateException ce) {
   throw ce;
  }
  finally {
   if (ps != null) {
    try {
     ps.close();
    }
    catch (Exception e) {
    }
   }
  }
  return new SimpleKey(id);
 }

  /**
  * ejbLoad
  */

 public void ejbLoad() throws javax.ejb.EJBException {

  Connection conn  = null;
  PreparedStatement ps = null;
  ResultSet rs = null;

  String loadSQL = null;

  try {
                    // call the common method to get the specific connection

   conn = getConnection();
  }
  catch (java.sql.SQLException sqle) {
   throw new EJBException("SQLException caught: " + sqle.getMessage());
  }
  catch (javax.resource.ResourceException re) {
   throw new EJBException(
    "ResourceException caught: " + re.getMessage());
  }

  // You need to determine which select statement to be used based on the
  // AccessIntent type:
  // If READ, then uses a normal SELECT statement. Otherwise uses a
  // SELECT...FORUPDATE statement
  // If your backend is SQLServer, then you can use different syntax for
  // the FOR UPDATE clause.

  if (intent.getAccessType() == AccessIntent.ACCESS_TYPE_READ) {
   loadSQL = "SELECT * FROM " + tableName + " WHERE id = ?";
  }
  else {
   loadSQL = "SELECT * FROM " + tableName + " WHERE id = ? FOR UPDATE";
  }

  SimpleKey key = (SimpleKey) getEntityContext().getPrimaryKey();

  try {
   ps = conn.prepareStatement(loadSQL);
   ps.setInt(1, key.id);
   rs = ps.executeQuery();
   if (rs.next()) {
    id = rs.getInt(1);
    name = rs.getString(2);
   }
   else {
    throw new EJBException("Cannot load id = " + key.id);
   }
  }
  catch (SQLException sqle) {
   throw new EJBException(sqle.getMessage());
  }
  finally {
   try {
    if (rs != null)
     rs.close();
   }
   catch (Exception e) {
   }
   try {
    if (ps != null)
     ps.close();
   }
   catch (Exception e) {
   }
   try {
    if (conn != null)
     conn.close();
   }
   catch (Exception e) {
   }
  }
 }

        /**
         * This method will use the AccessIntentService to get the access intent;
         * then gets the isolation level from the DataStoreHelper
         * and sets it in the connection spec; then uses this connection
         * spec to get a connection which has the specific connection
         * properties.
         **/

 private Connection getConnection()
  throws java.sql.SQLException, javax.resource.ResourceException, EJBException {

  // get current access intent object using EJB context
  intent = aiService.getAccessIntent(myEntityCtx);
  
  // Assume this bean only supports the pessimistic concurrency
  if (intent.getConcurrencyControl()
   != AccessIntent.CONCURRENCY_CONTROL_PESSIMISTIC) {
   throw new EJBException("Bean supports only pessimistic concurrency");
  }

  // determine correct isolation level for currently configured database 
  // using DataStoreHelper
  int isoLevel =
   WSCallHelper.getDataStoreHelper(ds).getIsolationLevel(intent);
   connSpec = WSRRAFactory.createJDBCConnectionSpec();
  connSpec.setTransactionIsolation(isoLevel);

  // Get connection using connection spec
  Connection conn = ((WSDataSource) ds).getConnection(connSpec);
  return conn;
 }



関連概念
リソース・アダプター
共用不可能接続および共用可能接続
関連資料
データ・アクセス API に対する拡張機能
参照トピック    

ご利用条件 | フィードバック

最終更新: Jan 21, 2008 5:05:53 PM EST
http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.base.doc/info/aes/ae/rdat_extiapi2.html