プラグイン・スロットの概要

プラグイン・スロットは、トランザクション・コンテキストを共有するプラグイン用に予約された、トランザクション・ストレージ・スペースです。これらの スロットは、eXtreme Scale プラグインが 互いに通信し、トランザクション・コンテキストを共有し、トランザクション内でトランザクション・リソースが整合性を保って正しく使用される ようにする手段を提供します。

プラグイン は、トランザクション・コンテキスト (データベース接続、Java Message Service (JMS) 接続など) をプラグイン・スロットに 保管できます。保管されたトランザクション・コンテキストは、プラグイン・スロット番号 (トランザクション・コンテキストを検索するキーとして機能する) を認識しているいずれのプラグインからも検索することができます。

プラグイン・スロットの使用

プラグイン・スロットは TxID インターフェースの一部です。 このインターフェースについて詳しくは、API 資料を参照してください。 スロットは、ArrayList 配列のエントリーです。 プラグインは、ObjectGrid.reserveSlot メソッドを呼び出し、すべての TxID オブジェクトでスロットが必要であることを示すことによって、ArrayList 配列のエントリーを予約できます。 スロットが予約されると、プラグインはそれぞれの TxID オブジェクトのスロットにトランザクション・コンテキストを保管し、後でそれを取得することができます。 put および get 操作は、ObjectGrid.reserveSlot メソッドから返されるスロット番号によって調整されます。

プラグインには通常、ライフサイクルがあります。プラグイン・スロットの使用はプラグインのライフサイクルに適合する必要があります。通常、プラグインは初期化ステージの間にプラグイン・スロットを予約し、それぞれのスロットのスロット番号を取得する必要があります。 標準的なランタイムでは、プラグインは適切なポイントで TxID オブジェクトの予約済みスロットにトランザクション・コンテキストを保管します。 このポイントは、通常はトランザクションの開始時点です。当該のプラグインまたは他のプラグインが、スロット番号によってトランザクション内の TxID から保管されたトランザクション・コンテキストを取得することができます。

通常、プラグインは、 トランザクション・コンテキストおよびスロットを削除することによってクリーンアップを実行します。 以下のコード・スニペットは、TransactionCallback プラグインでプラグイン・スロットを使用する方法を示しています。

public class DatabaseTransactionCallback implements TransactionCallback {
    int connectionSlot;
    int autoCommitConnectionSlot;
    int psCacheSlot;
    Properties ivProperties = new Properties();

    public void initialize(ObjectGrid objectGrid) throws TransactionCallbackException {
        // In initialization stage, reserve desired plug-in slots by calling the 
        //reserveSlot method of ObjectGrid and
        // passing in the designated slot name, TxID.SLOT_NAME.
        // Note: you have to pass in this TxID.SLOT_NAME that is designated 
        // for application.
        try {
            // cache the returned slot numbers
            connectionSlot = objectGrid.reserveSlot(TxID.SLOT_NAME);
            psCacheSlot = objectGrid.reserveSlot(TxID.SLOT_NAME);
            autoCommitConnectionSlot = objectGrid.reserveSlot(TxID.SLOT_NAME);
        } catch (Exception e) {
        }
    }

    public void begin(TxID tx) throws TransactionCallbackException {
        // put transactional contexts into the reserved slots at the 
        // beginning of the transaction.
        try {
            Connection conn = null;
            conn = DriverManager.getConnection(ivDriverUrl, ivProperties);
            tx.putSlot(connectionSlot, conn);
            conn = DriverManager.getConnection(ivDriverUrl, ivProperties);
            conn.setAutoCommit(true);
            tx.putSlot(autoCommitConnectionSlot, conn);
            tx.putSlot(psCacheSlot, new HashMap());
        } catch (SQLException e) {
            SQLException ex = getLastSQLException(e);
            throw new TransactionCallbackException("unable to get connection", ex);
        }
    }

    public void commit(TxID id) throws TransactionCallbackException {
        // get the stored transactional contexts and use them
        // then, clean up all transactional resources.
        try {
            Connection conn = (Connection) id.getSlot(connectionSlot);
            conn.commit();
            cleanUpSlots(id);
        } catch (SQLException e) {
            SQLException ex = getLastSQLException(e);
            throw new TransactionCallbackException("commit failure", ex);
        }
    }

    void cleanUpSlots(TxID tx) throws TransactionCallbackException {
        closePreparedStatements((Map) tx.getSlot(psCacheSlot));
        closeConnection((Connection) tx.getSlot(connectionSlot));
        closeConnection((Connection) tx.getSlot(autoCommitConnectionSlot));
    }

    /**
     * @param map
     */
    private void closePreparedStatements(Map psCache) {
        try {
            Collection statements = psCache.values();
            Iterator iter = statements.iterator();
            while (iter.hasNext()) {
                PreparedStatement stmt = (PreparedStatement) iter.next();
                stmt.close();
            }
        } catch (Throwable e) {
        }

    }

    /**
     * Close connection and swallow any Throwable that occurs.
     *
     * @param connection
     */
    private void closeConnection(Connection connection) {
        try {
            connection.close();
        } catch (Throwable e1) {
        }
    }

    public void rollback(TxID id) throws TransactionCallbackException
        // get the stored transactional contexts and use them
        // then, clean up all transactional resources.
        try {
            Connection conn = (Connection) id.getSlot(connectionSlot);
            conn.rollback();
            cleanUpSlots(id);
        } catch (SQLException e) {
        }
    }

    public boolean isExternalTransactionActive(Session session) {
        return false;
    }

    // Getter methods for the slot numbers, other plug-in can obtain the slot numbers 
    // from these getter methods.

    public int getConnectionSlot() {
        return connectionSlot;
    }
    public int getAutoCommitConnectionSlot() {
        return autoCommitConnectionSlot;
    }
    public int getPreparedStatementSlot() {
        return psCacheSlot;
    }

以下のコード・スニペットは、直前の TransactionCallback プラグインの例で保管されたトランザクション・コンテキストを、Loader が取得する方法の例を示しています。

public class DatabaseLoader implements Loader
{
    DatabaseTransactionCallback tcb;
    public void preloadMap(Session session, BackingMap backingMap) throws LoaderException
    {
        // The preload method is the initialization method of the Loader.
        // Obtain interested plug-in from Session or ObjectGrid instance.
        tcb = 
			(DatabaseTransactionCallback)session.getObjectGrid().getTransactionCallback();
    }
    public List get(TxID txid, List keyList, boolean forUpdate) throws LoaderException
    {
        // get the stored transactional contexts that is put by tcb's begin method.
        Connection conn = (Connection)txid.getSlot(tcb.getConnectionSlot());
        // implement get here
        return null;
    }
    public void batchUpdate(TxID txid, LogSequence sequence) throws LoaderException, 
			OptimisticCollisionException
    {
        // get the stored transactional contexts that is put by tcb's begin method.
        Connection conn = (Connection)txid.getSlot(tcb.getConnectionSlot());
        // implement batch update here ...
    }
}