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 }