001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.hayabusa.taglib; 017 018import org.opengion.fukurou.db.Transaction; 019import org.opengion.fukurou.db.TransactionImpl; 020import org.opengion.fukurou.util.ToString; // 6.1.1.0 (2015/01/17) 021 022/** 023 * コネクションを共有して、トランザクションを実現します。 024 * 025 * 通常のタグでは、コネクションプールより、その時々のコネクションを取り出して利用するため、 026 * タグごとに異なるコネクションで処理されます。 027 * また、commit や rollback などもそれぞれのタグで行われるため、連続処理時にエラーが 028 * 発生しても、中途半端な状態になります。 029 * ここでは、各 DBID 単位にコネクションを共有し、このタグの間は、同じオブジェクトを 030 * commit や、rollback せずに使いまわすようにします。 031 * これにより、複数タグ間のトランザクションや、異なる DBID 間のトランザクションを 032 * 実現します。 033 * 034 * このタグは、doEndTag() メソッドが正常に呼び出されることで、トランザクションが成立します。 035 * つまり、途中で、JSP出力が、SKIP_PAGE された場合は、commit もされません。 036 * これは、データベースエラー以外のエラーでも、トランザクション処理されることを意味します。 037 * 038 * @og.formSample 039 * ●形式:<og:transaction > ... </og:transaction > 040 * ●body:あり(EVAL_BODY_INCLUDE:BODYをインクルードし、{@XXXX} は解析しません) 041 * 042 * ●Tag定義: 043 * <og:transaction 044 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 045 * > ... Body ... 046 * </og:transaction> 047 * 048 * ●使用例 049 * <og:transaction > 050 * <og:query command="NEW" dbid="SERVER1" > 051 * insert into XX01 (aa,bb,cc) values ('AA','BB','CC') /> 052 * </og:query > 053 * <og:query command="NEW" dbid="SERVER2" > 054 * update YY02 set aa='AA',bb='BB',cc='CC' where uniq='00001' /> 055 * </og:query > 056 * </og:transaction > 057 * 058 * @og.rev 5.1.9.0 (2010/08/01) 新規作成 059 * @og.group DB登録 060 * 061 * @version 5.0 062 * @author Kazuhiko Hasegawa 063 * @since JDK6.0, 064 */ 065public class TransactionTag extends CommonTagSupport { 066 /** このプログラムのVERSION文字列を設定します。 {@value} */ 067 private static final String VERSION = "6.4.3.3 (2016/03/04)" ; 068 private static final long serialVersionUID = 643320160304L ; 069 070 // TransactionTag では、Transaction インターフェースではなく、実装クラスで管理します。 071 private transient TransactionImpl tran; // 6.3.9.0 (2015/11/06) transient 追加 072 073 /** 074 * デフォルトコンストラクター 075 * 076 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 077 */ 078 public TransactionTag() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 079 080 /** 081 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 082 * 083 * @return 後続処理の指示( EVAL_BODY_INCLUDE ) 084 */ 085 @Override 086 public int doStartTag() { 087 tran = new TransactionImpl( getApplicationInfo() ); 088 089 return EVAL_BODY_INCLUDE ; // Body インクルード( extends TagSupport 時) 090 } 091 092 /** 093 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 094 * 095 * TransactionTag の doEndTag() では、途中で、SKIP_PAGE されると、呼ばれません。 096 * これは、データベース以外のタグで、エラー等が発生したことになります。 097 * 最後の、endCommit() が呼ばれない限り、トランザクションは commit されずに、 098 * rollback されます。 099 * 100 * @og.rev 6.3.6.1 (2015/08/28) AutoCloseable の close() メソッドに対応。正常時は、commit()。 101 * @og.rev 6.4.3.3 (2016/03/04) 一般的なタグで、SKIP_PAGE された場合、rollback するようにします。 102 * 103 * @return 後続処理の指示 104 */ 105 @Override 106 public int doEndTag() { 107 debugPrint(); // 4.0.0 (2005/02/28) 108 109 if( tran != null ) { tran.endCommit(); } // 6.4.3.3 (2016/02/26 110 111 return EVAL_PAGE ; // ページの残りを評価する。 112 } 113 114 /** 115 * タグの処理中(セッターメソッドを除く)の例外を全て受け取ります。 116 * 117 * タグの中のボディ部の評価中、または Tag.doStartTag(), Tag.doEndTag(), 118 * IterationTag.doAfterBody(), BodyTag.doInitBody() のいずれもの 119 * メソッドの中で、Throwableが投げられたときに呼び出されます。 120 * 121 * このメソッドはセッターメソッドの中でThrowableが起きた場合は呼び出されません。 122 * 123 * @og.rev 6.3.6.1 (2015/08/28) AutoCloseable の close() メソッドに対応。異常時は、rollback()。 124 * 125 * @param th このタグを通過してきたThrowableな例外 126 */ 127 @Override 128 public void doCatch( final Throwable th ) throws Throwable { 129 if( tran != null ) { tran.rollback(); } 130 super.doCatch( th ); 131 } 132 133 /** 134 * タグリブオブジェクトをリリースします。 135 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 136 * 137 * @og.rev 6.3.6.1 (2015/08/28) AutoCloseable の close() メソッドに対応。終了時は、finish()。 138 */ 139 @Override 140 protected void release2() { 141 super.release2(); 142 143 // finish() は、TransactionImpl のメソッドです。 144 if( tran != null ) { tran.finish(); } 145 tran = null; 146 } 147 148 /** 149 * Transactionオブジェクトを返します。 150 * 151 * @og.rev 6.3.6.1 (2015/08/28) Transactionオブジェクトの取得方法変更。 152 * 153 * @return Transactionオブジェクト 154 */ 155 protected Transaction getTranObj() { 156 return tran ; 157 } 158 159 /** 160 * このオブジェクトの文字列表現を返します。 161 * 基本的にデバッグ目的に使用します。 162 * 163 * @return このクラスの文字列表現 164 * @og.rtnNotNull 165 */ 166 @Override 167 public String toString() { 168 return ToString.title( this.getClass().getName() ) 169 .println( "VERSION" ,VERSION ) 170 .println( "Other..." ,getAttributes().getAttribute() ) 171 .fixForm().toString() ; 172 } 173}