001 package railo.runtime.db; 002 003 004 import java.sql.Connection; 005 import java.sql.SQLException; 006 007 import railo.runtime.PageContext; 008 import railo.runtime.PageContextImpl; 009 import railo.runtime.config.ConfigImpl; 010 import railo.runtime.engine.ThreadLocalPageContext; 011 import railo.runtime.exp.DatabaseException; 012 import railo.runtime.exp.ExceptionHandler; 013 import railo.runtime.exp.PageException; 014 import railo.runtime.orm.ORMDatasourceConnection; 015 import railo.runtime.orm.ORMSession; 016 017 /** 018 * this class handle multible db connection, transaction and logging 019 */ 020 public final class DatasourceManagerImpl implements DataSourceManager { 021 022 private ConfigImpl config; 023 024 boolean autoCommit=true; 025 private int isolation=Connection.TRANSACTION_NONE; 026 private DatasourceConnection transConn; 027 028 029 /** 030 * constructor of the class 031 * @param pc 032 */ 033 public DatasourceManagerImpl(ConfigImpl c) { 034 this.config=c; 035 } 036 037 /** 038 * FUTURE deprecated 039 * @see DataSourceManager#getConnection(PageContext pc,java.lang.String, java.lang.String, java.lang.String) 040 */ 041 public DatasourceConnection getConnection(PageContext pc,String _datasource, String user, String pass) throws PageException { 042 return getConnection(pc,pc.getConfig().getDataSource(_datasource), user, pass); 043 } 044 045 // FUTURE add to interface 046 public DatasourceConnection getConnection(PageContext pc,DataSource ds, String user, String pass) throws PageException { 047 if(autoCommit) 048 return config.getDatasourceConnectionPool().getDatasourceConnection(pc,ds,user,pass); 049 050 051 pc=ThreadLocalPageContext.get(pc); 052 DatasourceConnection dc=((PageContextImpl)pc)._getConnection(ds,user,pass); 053 054 // transaction 055 //if(!autoCommit) { 056 try { 057 if(transConn==null) { 058 dc.getConnection().setAutoCommit(false); 059 060 if(isolation!=Connection.TRANSACTION_NONE) 061 dc.getConnection().setTransactionIsolation(isolation); 062 transConn=dc; 063 } 064 else if(!transConn.equals(dc)) { 065 if("_queryofquerydb".equalsIgnoreCase(ds.getName())) return dc; 066 throw new DatabaseException( 067 "can't use different connections inside a transaction",null,null,dc); 068 } 069 else if(dc.getConnection().getAutoCommit()) { 070 dc.getConnection().setAutoCommit(false); 071 } 072 } catch (SQLException e) { 073 ExceptionHandler.printStackTrace(e); 074 } 075 //} 076 return dc; 077 } 078 079 080 public void add(PageContext pc,ORMSession session) throws PageException { 081 082 // transaction 083 if(!autoCommit) { 084 try { 085 if(transConn==null) { 086 ORMDatasourceConnection dc=new ORMDatasourceConnection(pc,session); 087 088 if(isolation!=Connection.TRANSACTION_NONE) 089 dc.getConnection().setTransactionIsolation(isolation); 090 transConn=dc; 091 } 092 else if(!(transConn instanceof ORMDatasourceConnection)){ 093 /*if(transConn.getDatasource().equals(session.getEngine().getDataSource())){ 094 ORMDatasourceConnection dc=new ORMDatasourceConnection(pc,session); 095 096 if(isolation!=Connection.TRANSACTION_NONE) 097 dc.getConnection().setTransactionIsolation(isolation); 098 transConn=dc; 099 } 100 else*/ 101 throw new DatabaseException( 102 "can't use transaction for datasource and orm at the same time",null,null,null); 103 } 104 } catch (SQLException e) { 105 ExceptionHandler.printStackTrace(e); 106 } 107 } 108 } 109 110 /** 111 * @see railo.runtime.db.DataSourceManager#releaseConnection(railo.runtime.db.DatasourceConnection) 112 */ 113 public void releaseConnection(PageContext pc,DatasourceConnection dc) { 114 if(autoCommit) config.getDatasourceConnectionPool().releaseDatasourceConnection(dc); 115 } 116 117 /*private void releaseConnection(int pid,DatasourceConnection dc) { 118 config.getDatasourceConnectionPool().releaseDatasourceConnection(pid,dc); 119 }*/ 120 121 /** 122 * 123 * @see DataSourceManager#begin() 124 */ 125 public void begin() { 126 this.autoCommit=false; 127 this.isolation=Connection.TRANSACTION_NONE; 128 } 129 130 /** 131 * 132 * @see DataSourceManager#begin(java.lang.String) 133 */ 134 public void begin(String isolation) { 135 this.autoCommit=false; 136 137 if(isolation.equalsIgnoreCase("read_uncommitted")) 138 this.isolation=Connection.TRANSACTION_READ_UNCOMMITTED; 139 else if(isolation.equalsIgnoreCase("read_committed")) 140 this.isolation=Connection.TRANSACTION_READ_COMMITTED; 141 else if(isolation.equalsIgnoreCase("repeatable_read")) 142 this.isolation=Connection.TRANSACTION_REPEATABLE_READ; 143 else if(isolation.equalsIgnoreCase("serializable")) 144 this.isolation=Connection.TRANSACTION_SERIALIZABLE; 145 else 146 this.isolation=Connection.TRANSACTION_NONE; 147 148 } 149 /** 150 * 151 * @see DataSourceManager#begin(int) 152 */ 153 public void begin(int isolation) { 154 //print.out("begin:"+autoCommit); 155 this.autoCommit=false; 156 this.isolation=isolation; 157 } 158 159 /** 160 * 161 * @see DataSourceManager#rollback() 162 */ 163 public void rollback() throws DatabaseException { 164 if(autoCommit)return; 165 //autoCommit=true; 166 if(transConn!=null) { 167 try { 168 transConn.getConnection().rollback(); 169 //transConn.setAutoCommit(true); 170 } 171 catch (SQLException e) { 172 throw new DatabaseException(e,transConn); 173 } 174 //transConn=null; 175 } 176 } 177 178 // FUTURE add to interface 179 public void savepoint() throws DatabaseException { 180 if(autoCommit)return; 181 //autoCommit=true; 182 if(transConn!=null) { 183 try { 184 transConn.getConnection().setSavepoint(); 185 } 186 catch (SQLException e) { 187 throw new DatabaseException(e,transConn); 188 } 189 } 190 } 191 192 /** 193 * 194 * @see DataSourceManager#commit() 195 */ 196 public void commit() throws DatabaseException { 197 //print.out("commit:"+autoCommit); 198 if(autoCommit)return ; 199 //autoCommit=true; 200 if(transConn!=null) { 201 try { 202 transConn.getConnection().commit(); 203 //transConn.setAutoCommit(true); 204 } 205 catch (SQLException e) { 206 throw new DatabaseException(e,transConn); 207 } 208 //transConn=null; 209 } 210 } 211 212 /** 213 * 214 * @see DataSourceManager#isAutoCommit() 215 */ 216 public boolean isAutoCommit() { 217 return autoCommit; 218 } 219 220 /** 221 * 222 * @see DataSourceManager#end() 223 */ 224 public void end() { 225 autoCommit=true; 226 if(transConn!=null) { 227 try { 228 transConn.getConnection().setAutoCommit(true); 229 } 230 catch (SQLException e) { 231 ExceptionHandler.printStackTrace(e); 232 } 233 transConn=null; 234 } 235 } 236 237 public void remove(String datasource) { 238 config.getDatasourceConnectionPool().remove(datasource); 239 } 240 241 public void release() { 242 this.transConn=null; 243 this.isolation=Connection.TRANSACTION_NONE; 244 } 245 246 }