KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > connector > outbound > transactionlog > JDBCLog


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.geronimo.connector.outbound.transactionlog;
19
20 import java.sql.Connection JavaDoc;
21 import java.sql.PreparedStatement JavaDoc;
22 import java.sql.ResultSet JavaDoc;
23 import java.sql.SQLException JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28
29 import javax.sql.DataSource JavaDoc;
30 import javax.transaction.xa.Xid JavaDoc;
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 /**
42  * "Last Resource optimization" for single servers wishing to have valid xa transactions with
43  * a single 1-pc datasource. The database is used for the log, and the database work is
44  * committed when the log writes its prepare record.
45  *
46  * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
47  */

48 public class JDBCLog implements TransactionLog, GBeanLifecycle {
49     private final static String JavaDoc INSERT_XID = "INSERT INTO TXLOG (SYSTEMID, FORMATID, GLOBALID, GLOBALBRANCHID, BRANCHBRANCHID, NAME) VALUES (?, ?, ?, ?, ?)";
50     private final static String JavaDoc DELETE_XID = "DELETE FROM TXLOG WHERE SYSTEMID = ? AND FORMATID = ? AND GLOBALID = ? AND GLOBALBRANCHID = ?";
51     private final static String JavaDoc RECOVER = "SELECT FORMATID, GLOBALID, GLOBALBRANCHID, BRANCHBRANCHID, NAME FROM TXLOG WHERE SYSTEMID = ? ORDER BY FORMATID, GLOBALID, GLOBALBRANCHID, BRANCHBRANCHID, NAME";
52
53     private DataSource JavaDoc dataSource;
54     private final String JavaDoc systemId;
55     private final ConnectionFactorySource managedConnectionFactoryWrapper;
56
57     public JDBCLog(String JavaDoc systemId, ConnectionFactorySource managedConnectionFactoryWrapper) {
58         this.systemId = systemId;
59         this.managedConnectionFactoryWrapper = managedConnectionFactoryWrapper;
60     }
61
62     public JDBCLog(String JavaDoc systemId, DataSource JavaDoc dataSource) {
63         this.systemId = systemId;
64         this.managedConnectionFactoryWrapper = null;
65         this.dataSource = dataSource;
66     }
67
68     public void doStart() throws Exception JavaDoc {
69         dataSource = (DataSource JavaDoc) managedConnectionFactoryWrapper.$getResource();
70     }
71
72     public void doStop() throws Exception JavaDoc {
73         dataSource = null;
74     }
75
76     public void doFail() {
77     }
78
79     public void begin(Xid JavaDoc xid) throws LogException {
80     }
81
82     public Object JavaDoc prepare(Xid JavaDoc xid, List JavaDoc branches) throws LogException {
83         int formatId = xid.getFormatId();
84         byte[] globalTransactionId = xid.getGlobalTransactionId();
85         byte[] branchQualifier = xid.getBranchQualifier();
86         try {
87             Connection JavaDoc connection = dataSource.getConnection();
88             try {
89                 PreparedStatement JavaDoc ps = connection.prepareStatement(INSERT_XID);
90                 try {
91                     for (Iterator JavaDoc 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 JavaDoc e) {
111             throw new LogException("Failure during prepare or commit", e);
112         }
113         return null;
114     }
115
116     public void commit(Xid JavaDoc xid, Object JavaDoc logMark) throws LogException {
117         try {
118             Connection JavaDoc connection = dataSource.getConnection();
119             try {
120                 PreparedStatement JavaDoc 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 JavaDoc e) {
137             throw new LogException("Failure during prepare or commit", e);
138         }
139     }
140
141     public void rollback(Xid JavaDoc xid, Object JavaDoc 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 JavaDoc recover(XidFactory xidFactory) throws LogException {
146         try {
147             Connection JavaDoc connection = dataSource.getConnection();
148             try {
149                 Collection JavaDoc recovered = new ArrayList JavaDoc();
150                 PreparedStatement JavaDoc ps = connection.prepareStatement(RECOVER);
151                 try {
152                     ps.setString(0, systemId);
153                     ResultSet JavaDoc rs = ps.executeQuery();
154                     try {
155                         Xid JavaDoc lastXid = null;
156                         Xid JavaDoc 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 JavaDoc name = rs.getString(4);
164                             currentXid = xidFactory.recover(formatId, globalId, globalBranchId);
165                             Xid JavaDoc 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 JavaDoc e) {
184             throw new LogException("Recovery failure", e);
185         }
186
187     }
188
189     public String JavaDoc 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