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 }