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 */ 016 package org.opengion.fukurou.db; 017 018 import org.opengion.fukurou.util.Closer; 019 import org.opengion.fukurou.util.ApplicationInfo; 020 021 import java.sql.Connection; 022 023 import java.util.Locale; 024 import java.util.Map; 025 import java.util.HashMap; 026 027 /** 028 * コネクションを?有して、トランザクションを実現します? 029 * 030 * 基本?は、TransactionTag で利用されますが、?、このオブジェクトを 031 * 渡して、直接、利用するケースもあります? 032 * 033 * トランザクションがすべて完?た後で、realClose() メソ?を呼び出します? 034 * ?でも?rollback が指定されて?ば、ロールバックを行い、コネクション? 035 * 破?ます?それ以外で、commit が指定されて?ば、コミットを行い? 036 * コネクションを?プ?ルに戻します?どちらも?されて?ければ? 037 * コネクションプ?ルに戻すだけになります? 038 * 039 * ?方として、下記?ような流れになります? 040 * <pre> 041 * TransactionImpl tran = new TransactionImpl( appInfo ) ; 042 * try { 043 * ・・・・・ 044 * tran.commit(); 045 * tran.finish(); 046 * } 047 * catch( Exception ex ) { 048 * tran.rollback(); 049 * } 050 * finally { 051 * tran.realClose() 052 * } 053 * </pre> 054 * 055 * @og.rev 5.1.9.0 (2010/08/01) 新規作? 056 * 057 * @version 5.0 058 * @author Kazuhiko Hasegawa 059 * @since JDK6.0, 060 */ 061 public class TransactionImpl implements Transaction { 062 //* こ?プログラ??VERSION??を設定します? {@value} */ 063 private static final String VERSION = "5.3.8.0 (2011/08/01)" ; 064 065 private static final long serialVersionUID = 538020110801L ; 066 067 private static final String DBID = "DEFAULT"; 068 private final ApplicationInfo appInfo ; 069 070 private Connection defconn = null; // ?利用??高いDEFAULT?、別に変数を用意? 071 072 private final Map<String,Connection> dbidMap = new HashMap<String,Connection>(); 073 private boolean isCommit = false; 074 private boolean isRollback = false; 075 private boolean isError = false; 076 private boolean isFinish = false; 077 078 /** 079 * ApplicationInfo を指定して作?する、コンストラクター 080 * 081 * こ?クラスは、基本?は、TransactionTag クラスから作?されます? 082 * 083 * @param appInfo ?統制用のアクセス?? 084 */ 085 public TransactionImpl( final ApplicationInfo appInfo ) { 086 this.appInfo = appInfo ; 087 } 088 089 /** 090 * ??DBID に対応した?Connection オブジェクトを返します? 091 * ?Mapに存在して?ば、そのコネクションを?存在しなければ? 092 * 新しく作?します? 093 * 094 * @param dbid 接続?ID 095 * 096 * @return ??DBID に対応した?Connectionオブジェク? 097 */ 098 public Connection getConnection( final String dbid ) { 099 if( dbid == null || dbid.length() == 0 || DBID.equalsIgnoreCase( dbid ) ) { 100 if( defconn == null ) { 101 defconn = ConnectionFactory.connection( DBID,appInfo ); 102 } 103 return defconn; 104 } 105 106 String udbid = dbid.toUpperCase( Locale.JAPAN ); // 大?化 107 108 Connection conn = dbidMap.get( udbid ); 109 if( conn == null ) { 110 conn = ConnectionFactory.connection( udbid,appInfo ); 111 dbidMap.put( udbid,conn ); 112 } 113 114 return conn; 115 } 116 117 /** 118 * コミット??行われた場合に、?部フラグ(isCommit)?true にセ?します? 119 * ?回でもコミットが行われており、ロールバックが行われて?ければ? 120 * コミットされます? 121 * 122 * 検索処??みで、エラーが発生して???合?、コミットも行われな?ースがあります? 123 * 124 * @return 正常:true/異常:false 125 */ 126 public boolean commit() { 127 isCommit = true; 128 return true; 129 } 130 131 /** 132 * ロールバック処?行われた場合に、?部フラグ(isRollback)?true にセ?します? 133 * ?回でもロールバックが行われて?ば、最終的にはロールバックされます? 134 * 135 * ロールバック??場合?、isError フラグ?true(エラー?にセ?します? 136 * 137 * @return 正常:true/異常:false 138 */ 139 public boolean rollback() { 140 isRollback = true; 141 isError = true; 142 return true; 143 } 144 145 /** 146 * トランザクションの、終?処?行います? 147 * 148 * 実質?は、なにもしません? 149 * 150 * @see #close( boolean ) 151 * 152 * @return 正常:true/異常:false 153 */ 154 public boolean close() { 155 return close( false ); 156 } 157 158 /** 159 * トランザクションの、終?処?行います? 160 * 161 * 引数は、正常かど?を判定するフラグです?異常の場合?、true をセ?します? 162 * ここでは、実際には何もしませんが???エラーフラグをセ?します? 163 * (エラーの場合?みセ?。リセ?はされません) 164 * ?でも?エラーが発生したコネクションは、??ます?それ以外?、?ールに戻します? 165 * 166 * @param errFlag [true:エラー状?false:通常] 167 * 168 * @return 正常:true/異常:false 169 */ 170 public boolean close( final boolean errFlag ) { 171 if( errFlag ) { isError = true; } 172 return true; 173 } 174 175 /** 176 * トランザクションとして、正常終?に処?行います? 177 * 178 * 実質?は、?部のfinishフラグをセ?する?です? 179 * ただし?こ?フラグがセ?されて???合?、??途中で止まっ? 180 * 可能性があるため?トランザクションとしては、正常終?せることができません? 181 * 182 * @see #realClose() 183 */ 184 public void finish() { 185 isFinish = true; 186 } 187 188 /** 189 * トランザクションとして、終?処?行います? 190 * 191 * トランザクションがすべて完?た後で、呼び出します? 192 * ?でも?Rollback が指定されて?ば、ロールバックを行い、コネクション? 193 * 破?ます?それ以外で、Commit が指定されて?ば、コミットを行い? 194 * コネクションを?プ?ルに戻します?どちらも?されて?ければ? 195 * コネクションプ?ルに戻すだけになります? 196 * 197 * @og.rev 5.3.8.0 (2011/08/01) ?変数を?期化し?こ?オブジェクトが再利用できるようにする? 198 */ 199 public void realClose() { 200 if( defconn != null ) { 201 connClose( defconn,DBID ); 202 } 203 204 for( Map.Entry<String,Connection> entry : dbidMap.entrySet() ) { 205 String dbid = entry.getKey(); 206 Connection conn = entry.getValue(); 207 208 connClose( conn,dbid ); 209 } 210 211 // ?変数を?期化します? 212 defconn = null; 213 214 // 5.3.8.0 (2011/08/01) ?変数を?期化し?こ?オブジェクトが再利用できるようにする? 215 // dbidMap = null; 216 dbidMap.clear(); 217 218 isCommit = false; 219 isRollback = false; 220 isError = false; 221 isFinish = false; 222 } 223 224 /** 225 * Connection オブジェクトをクローズします? 226 * 227 * 実際にはクローズせず、commit また?、rollback を行った後? 228 * エラー状況に応じて、ConnectionFactory に返却するか?削除します? 229 * なお?commit また?、rollback 時にエラーが発生した?合でも?無視して 230 * そ?まま、??継続します? 231 * 232 * @param conn クローズ処?行う、Connection オブジェク? 233 * @param dbid 接続?ID 234 */ 235 private void connClose( final Connection conn, final String dbid ) { 236 // まず?コミットかロールバックされた?合?、どちらかの処??? 237 if( isCommit || isRollback ) { 238 // commit できる条件?コミットされ?フィニッシュされ、エラーでなく?ロールバックでな? 239 if( isCommit && isFinish && (!isError) && (!isRollback) ) { 240 Closer.commit( conn ); 241 } 242 // それ以外?、ロールバックする? 243 else { 244 Closer.rollback( conn ); 245 } 246 } 247 248 // 残りは、コミットもロールバックもされて??め?単にキャ?ュへの返し方のみ判定する? 249 // isFinish されて??、エラーにもなって???合?、接続要因以外?問題なので、返却でよい? 250 if( isError ) { ConnectionFactory.remove( conn,dbid ); } // 削除 251 else { ConnectionFactory.close( conn,dbid ); } // 返却 252 253 } 254 }