SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

SpringとEJB 3.0の機能比較 第1回

持続性/トランザクション管理/ステートフルネスのサポートの比較

  • X ポスト
  • このエントリーをはてなブックマークに追加

トランザクション管理

 多くの企業向けアプリケーションで非常に重要なもう1つの要素が、トランザクション管理です。大規模なアプリケーションでは、多数のユーザーが同一のデータに同時にアクセスを試みる可能性があるためです。また、単独ユーザーでも複数ユーザーでも、通常は特定の操作を完全に成功させるか失敗させるかのどちらかにする必要があります。

トランザクション管理 - 機能の比較

 トランザクション性を備えたSpringおよびEJB 3.0の機能的性能を説明するために、航空券予約シナリオにおけるチケット購入の事例を考えてみましょう(図2を参照)。

図2 チケット購入のシーケンスダイアグラム。チケット購入シーケンスのどのステップで失敗が生じても、システムは整合性のある状態を維持する必要がある
図2 チケット購入のシーケンスダイアグラム。チケット購入シーケンスのどのステップで失敗が生じても、システムは整合性のある状態を維持する必要がある

 以下に示す単体テストは、このチケット購入の処理がトランザクション的な方法で機能することを検証するものです。

public void testPurchaseTicket_DebitFailure() throws Exception
{
    // Creates a pending ticket
    Ticket ticket = createTicket();

    // Store original ticket count from DB
    int count = ticketDAO.findAll().size();

    // Setup a credit authorizer which will throw an exception on debit
    setupMockAuthorizer(true);

    try
    {
        bookingAgent.purchaseTicket(ticket, true);

        fail("System failure was not thrown as was intended");
    }
    catch (InsufficientFundsException e)
    {
        // Correct behavior since we're testing transactional semantics
    }

    // Verify transaction rolled-back
    assertEquals(count, ticketDAO.findAll().size());
}

 このテストは、SpringとEJB 3.0のどちらの実装に対しても正しく実行することができます。Springによる実装は次のようになります。

public Ticket purchaseTicket(Ticket ticket)
{
    creditAuthorizer.authorize(ticket.getPrice(), null);

    ticket.setStatus(Status.PURCHASED);

    ticketDAO.save(ticket);

    creditAuthorizer.debit(ticket.getPrice());

    return ticket;
}

 これを以下のEJB 3.0仕様による実装と比較してみましょう。

public Ticket purchaseTicket(Ticket ticket)
{
    creditAuthorizer.authorize(ticket.getPrice(), null);

    ticket.setStatus(Status.PURCHASED);

    ticketDAO.save(ticket);

    creditAuthorizer.debit(ticket.getPrice());

    return ticket;
}

 両実装がまったく同じものであり、どちらもトランザクション管理を明示的に処理する必要がないことに注意してください。このことは宣言的プログラミングの真価をよく示しています。開発者は業務上の問題に重点を置いたコードを書くことができ、トランザクション性のような各分野共通の問題はモジュール化してアプリケーションの種類に関係なく適用することが可能なのです。この事例では、SpringもEJB 3.0もトランザクションの処理にあたって同等の機能を提供しており、どちらもビジネスロジックの煩雑化を防ぐやり方でこの機能のモジュール化に成功しています。

トランザクション管理 - 機能以外の比較

 検討すべきトランザクション管理の重要な側面として、境界設定(demarcation)、伝播(propagation)、分離(isolation)があります。境界設定とは、トランザクション的な意味で作業単位の境界を決める処理をいいます。また、複数のコンポーネントが協調する場合、コンポーネント間でトランザクションの共有(伝播)が必要になります。さらに、開発者によるトランザクション間の隔たりの度合いの調整を可能にしているのが分離レベルです。

 Springでは、トランザクションの境界設定、伝播、分離はすべてAOP(Aspect Oriented Programming)の機能を介して宣言されています。トランザクション的プロキシはそのXML設定フィルタ内で明示的に定義するか、アスペクト構文を使って適用することができます。トランザクション的プロキシにおけるワイヤリング方法を以下に示します。

<bean id="bookingAgent" class="org.springframework.transaction.
interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager" />
    <property name="target" ref="bookingAgentSpring" />
    <property name="transactionAttributes">
        <props>
            <prop key="*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

<bean id="bookingAgentSpring"
      class="org.jug.flight.booking.spring.BookingAgentSpring">
    <property name="flightDAO" ref="flightDAO" />
    <property name="ticketDAO" ref="ticketDAO" />
    <property name="screener" ref="screener" />
</bean>

 一方のEJB 3.0は、特別な設定が必要にならないように、セッションBeanのすべてのpublicメソッドに対してトランザクション的な意味を自動的に適用します。次に示すように、開発者は注釈またはXMLを用いてトランザクションの伝播レベルを調整できます。

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public Ticket purchaseTicket(Ticket ticket)
{
    ...
}

 EJB 3.0仕様はトランザクションの分離をリソースマネージャ特有の形で宣言するため、EJB 3.0にはこの要求を表現する標準的な方法がありません。SpringにはJDBC、Hibernate、JTAなど、さまざまな種類のトランザクションAPIが統合されていますが、EJB 3.0はJTAのトランザクションしかサポートしていません。トランザクションAPIの選択は、2つの初歩的な場合で重要になります。まず、すべてのEJBコンテナはJTAをサポートしていますが、すべてのコンテナがJTAをサポートしているわけではありません(例えばTomcatなど)。さらに、複数のリソース(JDBC、JMSなど)を1つの分散トランザクション内で連結するには、JTAによる実装が必要です。なお、JTAが必要なのにJTA実装を提供していない環境で作業を行う場合には、Java Open Transaction Manager(JOTM)のようなオープンソースのJTA実装を検討するとよいでしょう。

トランザクション管理 - まとめ

 SpringとEJB 3.0はどちらも、その持続性のメカニズムと互換性のあるトランザクション管理に対して統合化アプローチをとっています(表3を参照)。

表3 SpringとEJB 3.0で等価なトランザクション管理の機能
機能 Spring EJB 3.0
宣言的トランザクション
プログラム的トランザクション
境界設定AOPセッションBeanのメソッド
サポートするトランザクションの種類JDBC、Hibernate、JTAJTA
分散トランザクションのサポート√(JTAを使用)
設定XMLデフォルトはトランザクション的なもの、注釈またはXMLによるオーバーライドあり
標準√(JTA)

次のページ
ステートフルネス(状態管理性)

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Rod Coffin(Rod Coffin)

最新の開発プロセスおよびテクノロジの大規模導入のコンサルテーションを行うValtech Skill Developmentの上級顧問。主にエンタープライズJava開発およびアジャイル手法を行うチームを指導している。アスペクト指向プログラミングからEJB 3.0に至るまで各種の話題について数本の記事を...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/655 2006/10/25 00:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング