1 17 18 package org.apache.geronimo.connector.outbound.transactionlog; 19 20 import java.sql.Connection ; 21 import java.sql.PreparedStatement ; 22 import java.sql.ResultSet ; 23 import java.sql.SQLException ; 24 import java.util.ArrayList ; 25 import java.util.Collection ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 29 import javax.sql.DataSource ; 30 import javax.transaction.xa.Xid ; 31 32 import org.apache.geronimo.connector.outbound.ConnectionFactorySource; 33 import org.apache.geronimo.gbean.GBeanLifecycle; 34 import org.apache.geronimo.transaction.manager.LogException; 35 import org.apache.geronimo.transaction.manager.Recovery; 36 import org.apache.geronimo.transaction.manager.TransactionBranchInfo; 37 import org.apache.geronimo.transaction.manager.TransactionBranchInfoImpl; 38 import org.apache.geronimo.transaction.manager.TransactionLog; 39 import org.apache.geronimo.transaction.manager.XidFactory; 40 41 48 public class JDBCLog implements TransactionLog, GBeanLifecycle { 49 private final static String INSERT_XID = "INSERT INTO TXLOG (SYSTEMID, FORMATID, GLOBALID, GLOBALBRANCHID, BRANCHBRANCHID, NAME) VALUES (?, ?, ?, ?, ?)"; 50 private final static String DELETE_XID = "DELETE FROM TXLOG WHERE SYSTEMID = ? AND FORMATID = ? AND GLOBALID = ? AND GLOBALBRANCHID = ?"; 51 private final static String RECOVER = "SELECT FORMATID, GLOBALID, GLOBALBRANCHID, BRANCHBRANCHID, NAME FROM TXLOG WHERE SYSTEMID = ? ORDER BY FORMATID, GLOBALID, GLOBALBRANCHID, BRANCHBRANCHID, NAME"; 52 53 private DataSource dataSource; 54 private final String systemId; 55 private final ConnectionFactorySource managedConnectionFactoryWrapper; 56 57 public JDBCLog(String systemId, ConnectionFactorySource managedConnectionFactoryWrapper) { 58 this.systemId = systemId; 59 this.managedConnectionFactoryWrapper = managedConnectionFactoryWrapper; 60 } 61 62 public JDBCLog(String systemId, DataSource dataSource) { 63 this.systemId = systemId; 64 this.managedConnectionFactoryWrapper = null; 65 this.dataSource = dataSource; 66 } 67 68 public void doStart() throws Exception { 69 dataSource = (DataSource ) managedConnectionFactoryWrapper.$getResource(); 70 } 71 72 public void doStop() throws Exception { 73 dataSource = null; 74 } 75 76 public void doFail() { 77 } 78 79 public void begin(Xid xid) throws LogException { 80 } 81 82 public Object prepare(Xid xid, List branches) throws LogException { 83 int formatId = xid.getFormatId(); 84 byte[] globalTransactionId = xid.getGlobalTransactionId(); 85 byte[] branchQualifier = xid.getBranchQualifier(); 86 try { 87 Connection connection = dataSource.getConnection(); 88 try { 89 PreparedStatement ps = connection.prepareStatement(INSERT_XID); 90 try { 91 for (Iterator iterator = branches.iterator(); iterator.hasNext();) { 92 TransactionBranchInfo branch = (TransactionBranchInfo) iterator.next(); 93 ps.setString(0, systemId); 94 ps.setInt(1, formatId); 95 ps.setBytes(2, globalTransactionId); 96 ps.setBytes(3, branchQualifier); 97 ps.setBytes(4, branch.getBranchXid().getBranchQualifier()); 98 ps.setString(5, branch.getResourceName()); 99 ps.execute(); 100 } 101 } finally { 102 ps.close(); 103 } 104 if (!connection.getAutoCommit()) { 105 connection.commit(); 106 } 107 } finally { 108 connection.close(); 109 } 110 } catch (SQLException e) { 111 throw new LogException("Failure during prepare or commit", e); 112 } 113 return null; 114 } 115 116 public void commit(Xid xid, Object logMark) throws LogException { 117 try { 118 Connection connection = dataSource.getConnection(); 119 try { 120 PreparedStatement ps = connection.prepareStatement(DELETE_XID); 121 try { 122 ps.setString(0, systemId); 123 ps.setInt(1, xid.getFormatId()); 124 ps.setBytes(2, xid.getGlobalTransactionId()); 125 ps.setBytes(3, xid.getBranchQualifier()); 126 ps.execute(); 127 } finally { 128 ps.close(); 129 } 130 if (!connection.getAutoCommit()) { 131 connection.commit(); 132 } 133 } finally { 134 connection.close(); 135 } 136 } catch (SQLException e) { 137 throw new LogException("Failure during prepare or commit", e); 138 } 139 } 140 141 public void rollback(Xid xid, Object logMark) throws LogException { 142 throw new LogException("JDBCLog does not support rollback of prepared transactions. Use it only on servers that do not import transactions"); 143 } 144 145 public Collection recover(XidFactory xidFactory) throws LogException { 146 try { 147 Connection connection = dataSource.getConnection(); 148 try { 149 Collection recovered = new ArrayList (); 150 PreparedStatement ps = connection.prepareStatement(RECOVER); 151 try { 152 ps.setString(0, systemId); 153 ResultSet rs = ps.executeQuery(); 154 try { 155 Xid lastXid = null; 156 Xid currentXid = null; 157 Recovery.XidBranchesPair xidBranchesPair = null; 158 while (rs.next()) { 159 int formatId = rs.getInt(0); 160 byte[] globalId = rs.getBytes(1); 161 byte[] globalBranchId = rs.getBytes(2); 162 byte[] branchBranchId = rs.getBytes(3); 163 String name = rs.getString(4); 164 currentXid = xidFactory.recover(formatId, globalId, globalBranchId); 165 Xid branchXid = xidFactory.recover(formatId, globalId, branchBranchId); 166 if (!currentXid.equals(lastXid)) { 167 xidBranchesPair = new Recovery.XidBranchesPair(currentXid, null); 168 recovered.add(xidBranchesPair); 169 lastXid = currentXid; 170 } 171 xidBranchesPair.addBranch(new TransactionBranchInfoImpl(branchXid, name)); 172 } 173 return recovered; 174 } finally { 175 rs.close(); 176 } 177 } finally { 178 ps.close(); 179 } 180 } finally { 181 connection.close(); 182 } 183 } catch (SQLException e) { 184 throw new LogException("Recovery failure", e); 185 } 186 187 } 188 189 public String getXMLStats() { 190 return null; 191 } 192 193 public int getAverageForceTime() { 194 return 0; 195 } 196 197 public int getAverageBytesPerForce() { 198 return 0; 199 } 200 201 } 202 | Popular Tags |