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; 020 021import java.io.ObjectOutputStream; 022import java.io.ObjectInputStream; 023import java.io.IOException; 024 025/** 026 * コネクションを共有して、トランザクションを実現します。 027 * 028 * 通常のタグでは、コネクションプールより、その時々のコネクションを取り出して利用するため、 029 * タグごとに異なるコネクションで処理されます。 030 * また、commit や rollback などもそれぞれのタグで行われるため、連続処理時にエラーが 031 * 発生しても、中途半端な状態になります。 032 * ここでは、各 DBID 単位にコネクションを共有し、このタグの間は、同じオブジェクトを 033 * commit や、rollback せずに使いまわすようにします。 034 * これにより、複数タグ間のトランザクションや、異なる DBID 間のトランザクションを 035 * 実現します。 036 * 037 * このタグは、doEndTag() メソッドが正常に呼び出されることで、トランザクションが成立します。 038 * つまり、途中で、JSP出力が、SKIP_PAGE された場合は、commit もされません。 039 * これは、データベースエラー以外のエラーでも、トランザクション処理されることを意味します。 040 * 041 * @og.formSample 042 * ●形式:<og:transaction > ... </og:transaction > 043 * ●body:あり(EVAL_BODY_INCLUDE:BODYをインクルードし、{@XXXX} は解析しません) 044 * 045 * ●Tag定義: 046 * <og:transaction 047 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 048 * > ... Body ... 049 * </og:transaction> 050 * 051 * ●使用例 052 * <og:transaction > 053 * <og:query command="NEW" dbid="SERVER1" > 054 * insert into XX01 (aa,bb,cc) values ('AA','BB','CC') /> 055 * </og:query > 056 * <og:query command="NEW" dbid="SERVER2" > 057 * update YY02 set aa='AA',bb='BB',cc='CC' where uniq='00001' /> 058 * </og:query > 059 * </og:transaction > 060 * 061 * @og.rev 5.1.9.0 (2010/08/01) 新規作成 062 * @og.group DB登録 063 * 064 * @version 5.0 065 * @author Kazuhiko Hasegawa 066 * @since JDK6.0, 067 */ 068public class TransactionTag extends CommonTagSupport { 069 //* このプログラムのVERSION文字列を設定します。 {@value} */ 070 private static final String VERSION = "5.1.9.0 (2010/08/01)" ; 071 private static final long serialVersionUID = 519020100801L ; 072 073 // TransactionTag では、Transaction インターフェースではなく、実装クラスで管理します。 074 private TransactionImpl tran = null; 075 076 /** 077 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 078 * 079 * @return 後続処理の指示( EVAL_BODY_INCLUDE ) 080 */ 081 @Override 082 public int doStartTag() { 083 tran = new TransactionImpl( getApplicationInfo() ); 084 085 return( EVAL_BODY_INCLUDE ); // Body インクルード( extends TagSupport 時) 086 } 087 088 /** 089 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 090 * 091 * @return 後続処理の指示 092 */ 093 @Override 094 public int doEndTag() { 095 debugPrint(); // 4.0.0 (2005/02/28) 096 097 // finish() は、TransactionImpl のメソッドです。 098 if( tran != null ) { tran.finish(); } 099 100 return(EVAL_PAGE); // ページの残りを評価する。 101 } 102 103 /** 104 * タグリブオブジェクトをリリースします。 105 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 106 * 107 */ 108 @Override 109 protected void release2() { 110 super.release2(); 111 112 // realClose() は、TransactionImpl のメソッドです。 113 if( tran != null ) { tran.realClose(); } 114 tran = null; 115 } 116 117 /** 118 * Transactionオブジェクトを返します。 119 * 120 * @return Transactionオブジェクト 121 */ 122 protected Transaction getTransaction() { 123 return tran ; 124 } 125 126 /** 127 * シリアライズ用のカスタムシリアライズ書き込みメソッド 128 * 129 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 130 * @serialData 一部のオブジェクトは、シリアライズされません。 131 * 132 * @param strm ObjectOutputStreamオブジェクト 133 * @throws IOException 入出力エラーが発生した場合 134 */ 135 private void writeObject( final ObjectOutputStream strm ) throws IOException { 136 strm.defaultWriteObject(); 137 } 138 139 /** 140 * シリアライズ用のカスタムシリアライズ読み込みメソッド 141 * 142 * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。 143 * 144 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 145 * @serialData 一部のオブジェクトは、シリアライズされません。 146 * 147 * @param strm ObjectInputStreamオブジェクト 148 * @see #release2() 149 * @throws IOException シリアライズに関する入出力エラーが発生した場合 150 * @throws ClassNotFoundException クラスを見つけることができなかった場合 151 */ 152 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException { 153 strm.defaultReadObject(); 154 } 155 156 /** 157 * このオブジェクトの文字列表現を返します。 158 * 基本的にデバッグ目的に使用します。 159 * 160 * @return このクラスの文字列表現 161 */ 162 @Override 163 public String toString() { 164 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 165 .println( "VERSION" ,VERSION ) 166 .println( "Other..." ,getAttributes().getAttribute() ) 167 .fixForm().toString() ; 168 } 169}