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