1 package org.enhydra.dods.xa; 2 3 import java.sql.SQLException ; 4 import java.util.HashMap ; 5 6 import javax.naming.InitialContext ; 7 import javax.naming.NamingException ; 8 import javax.transaction.Status ; 9 import javax.transaction.SystemException ; 10 11 import org.enhydra.dods.CommonConstants; 12 import org.enhydra.dods.DODS; 13 14 import com.lutris.appserver.server.sql.AbstractDBTransactionFactory; 15 import com.lutris.appserver.server.sql.DBConnection; 16 import com.lutris.appserver.server.sql.DBTransaction; 17 import com.lutris.appserver.server.sql.DBTransactionFactoryCreator; 18 import com.lutris.appserver.server.sql.LogicalDatabase; 19 import com.lutris.appserver.server.sql.standard.DatabaseConfiguration; 20 import com.lutris.appserver.server.sql.standard.StandardLogicalDatabase; 21 import com.lutris.logging.Logger; 22 23 26 27 public class XAUserTransactionFactory implements AbstractDBTransactionFactory { 28 29 private boolean configured = false; 30 private LogicalDatabase logicalDb = null; 31 private HashMap dodsJtaThreadContext = new HashMap (); 32 private HashMap dodsSuspendedJtaContext = new HashMap (); 33 34 35 public void setLogicalDb(LogicalDatabase ldb) { 36 logicalDb=ldb; 37 } 38 public LogicalDatabase getLogicalDb() { 39 return logicalDb; 40 } 41 42 private AbstractDBTransactionFactory wrapedTransactionFactory; 43 private XATransactionFactory xaTransactionFactory; 44 private String strUserTransactionLookupName; 45 private String strTransactionManagerLookupName; 46 private String strWrappedImplFactory; 47 private int defaultTimeout = CommonConstants.DEFAULT_XA_DEFAULT_TIMEOUT; 48 private int jtaSupport; 49 private String strJtaSupport; 50 51 54 public DBTransaction getTransaction(DBConnection conn) throws SQLException { 55 if (!configured) { 56 try { 57 DatabaseConfiguration dbco = ((StandardLogicalDatabase)getLogicalDb()).getDatabaseConfiguration(); 58 strUserTransactionLookupName = dbco.getXaUserTransactonLookupName(); 59 strTransactionManagerLookupName = dbco.getXaTransactonManagerLookupName(); 60 strWrappedImplFactory = dbco.getXaWrappedTransImplFactory(); 61 strJtaSupport = dbco.getXaJtaSupport(); 62 defaultTimeout = dbco.getXaDefaultTimeout(); 63 jtaSupport = getJtaSupportIntValue(strJtaSupport); 64 wrapedTransactionFactory = DBTransactionFactoryCreator.getDBTransactionFactory(strWrappedImplFactory,getLogicalDb()); 65 xaTransactionFactory = (XATransactionFactory)DBTransactionFactoryCreator.getDBTransactionFactory("org.enhydra.dods.xa.XATransactionFactory",getLogicalDb()); 66 configured = true; 67 } catch (Exception e) { 68 DODS.getLogChannel().write(Logger.CRITICAL,"Creating XAUserTransactionFactory faild" ); 69 e.printStackTrace(); 70 throw new SQLException ("Unable to create new UserTransaction"); 71 } 72 } 73 74 javax.transaction.TransactionManager tm = null; 75 int jtaStatus = Status.STATUS_NO_TRANSACTION; 76 try { 77 tm = getTransactionManager(); 78 jtaStatus = tm.getStatus(); 79 } catch (NamingException e) { 80 throw new SQLException (); 81 } catch (SystemException e) { 82 throw new SQLException (); 83 } 84 85 switch (jtaSupport){ 86 87 case CommonConstants.JTA_MANDATORY:{ 89 if (jtaStatus == Status.STATUS_NO_TRANSACTION) { 90 throw new SQLException ("UserTransaction required Error"); 91 }else { 92 return xaTransactionFactory.getTransaction(conn); 93 } 94 } 95 96 case CommonConstants.JTA_REQUIRED:{ 98 if (jtaStatus == Status.STATUS_NO_TRANSACTION) { 99 try { 100 return new XAUserTransaction(conn, strUserTransactionLookupName, defaultTimeout,this, xaTransactionFactory); 101 }catch (Exception e){ 102 throw new SQLException (e.getMessage()); 103 } 104 }else { 105 return xaTransactionFactory.getTransaction(conn); 106 } 107 } 108 109 case CommonConstants.JTA_REQUIRES_NEW:{ 111 if (jtaStatus == Status.STATUS_NO_TRANSACTION) { 112 try { 113 return new XAUserTransaction(conn, strUserTransactionLookupName, defaultTimeout,this, xaTransactionFactory); 114 }catch (Exception e){ 115 throw new SQLException (e.getMessage()); 116 } 117 }else { 118 if(this.checkDodsJtaThreadContext()) { 119 return xaTransactionFactory.getTransaction(conn); 120 } else { 121 try { 122 javax.transaction.Transaction xaSuspended = tm.suspend(); 123 XAUserTransaction xaut= new XAUserTransaction(conn, strUserTransactionLookupName, defaultTimeout,this, xaTransactionFactory); 124 synchronized(dodsSuspendedJtaContext) { 125 dodsSuspendedJtaContext.put(xaut,xaSuspended); 126 } 127 } catch (Exception e) { 128 throw new SQLException (); 129 } 130 } 131 } 132 } 133 134 case CommonConstants.JTA_SUPPORTS:{ 136 if(jtaStatus==Status.STATUS_NO_TRANSACTION) { 137 return wrapedTransactionFactory.getTransaction(conn); 138 }else { 139 return xaTransactionFactory.getTransaction(conn); 140 } 141 } 142 143 case CommonConstants.JTA_NOT_SUPPORTED:{ 145 return wrapedTransactionFactory.getTransaction(conn); 146 } 147 148 case CommonConstants.JTA_NEVER:{ 150 if(jtaStatus==Status.STATUS_NO_TRANSACTION) { 151 throw new SQLException ("Parameter 'JtaSupport=NEVER' Required to create transaction " + 152 "outside of any UserTransaction context"); 153 } 154 return wrapedTransactionFactory.getTransaction(conn); 155 } 156 157 default:{ 158 throw new SQLException ("Undefined value for 'JtaSupport' parameter = "+strJtaSupport+"("+ jtaSupport+")"); 159 } 160 } 161 } 162 163 164 168 protected javax.transaction.TransactionManager getTransactionManager() throws NamingException { 169 javax.transaction.TransactionManager tm; 170 InitialContext ictx = new InitialContext (); 171 tm = (javax.transaction.TransactionManager ) ictx.lookup(strTransactionManagerLookupName); 172 return tm; 173 } 174 175 176 protected void makeDodsJtaThreadContext(XAUserTransaction xaut) 177 throws SQLException { 178 synchronized (dodsJtaThreadContext) { 179 Thread currentThread = Thread.currentThread(); 180 if(!dodsJtaThreadContext.containsKey(currentThread)) { 181 dodsJtaThreadContext.put(Thread.currentThread(),new Boolean (true)); 182 }else { 183 throw new SQLException ("Error during creation of Dods Jta Thread Context"); 184 } 185 } 186 } 187 188 protected boolean checkDodsJtaThreadContext() { 189 synchronized (dodsJtaThreadContext) { 190 return dodsJtaThreadContext.containsKey(Thread.currentThread()); 191 } 192 } 193 194 protected void closeDodsJtaThreadContext(XAUserTransaction xaut) 195 throws SQLException { 196 try { 197 this.resumeJtaContext(xaut); 198 } catch (Exception e) { 199 throw new SQLException (); 200 }finally { 201 Thread currentThread = Thread.currentThread(); 202 synchronized (dodsJtaThreadContext) { 203 if(dodsJtaThreadContext.containsKey(currentThread)) { 204 dodsJtaThreadContext.remove(Thread.currentThread()); 205 }else { 206 throw new SQLException ("Error during close of Dods Jta Thread Context"); 207 } 208 } 209 } 210 } 211 212 protected void resumeJtaContext(XAUserTransaction xaut) 213 throws SQLException { 214 try { 215 javax.transaction.Transaction t ; 216 synchronized(dodsSuspendedJtaContext) { 217 t = (javax.transaction.Transaction )dodsSuspendedJtaContext.remove(xaut); 218 } 219 if(t!=null) { 220 getTransactionManager().resume(t); 221 } 222 } catch (Exception e) { 223 throw new SQLException (); 224 } 225 } 226 227 private int getJtaSupportIntValue(String strValue) { 228 for(int i=0; i<CommonConstants.XA_JTA_SUPPORT_VALUES.length;i++) { 229 if(CommonConstants.XA_JTA_SUPPORT_VALUES[i].equalsIgnoreCase(strValue)) { 230 return i; 231 } 232 } 233 return -1; 234 } 235 } 236 | Popular Tags |