source: Ballon/out/artifacts/geisa_artifact/WEB-INF/lib/mysql-connector-java-5.1.21/src/com/mysql/jdbc/jdbc2/optional/SuspendableXAConnection.java @ 766

Last change on this file since 766 was 766, checked in by npipsl, 11 years ago
File size: 6.1 KB
Line 
1/*
2 Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
3 
4
5  The MySQL Connector/J is licensed under the terms of the GPLv2
6  <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most MySQL Connectors.
7  There are special exceptions to the terms and conditions of the GPLv2 as it is applied to
8  this software, see the FLOSS License Exception
9  <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
10
11  This program is free software; you can redistribute it and/or modify it under the terms
12  of the GNU General Public License as published by the Free Software Foundation; version 2
13  of the License.
14
15  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
16  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17  See the GNU General Public License for more details.
18
19  You should have received a copy of the GNU General Public License along with this
20  program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth
21  Floor, Boston, MA 02110-1301  USA
22
23
24
25 */
26
27package com.mysql.jdbc.jdbc2.optional;
28
29
30import java.lang.reflect.Constructor;
31import java.sql.SQLException;
32import java.util.HashMap;
33import java.util.Map;
34
35import javax.sql.XAConnection;
36import javax.transaction.xa.XAException;
37import javax.transaction.xa.XAResource;
38import javax.transaction.xa.Xid;
39
40import com.mysql.jdbc.ConnectionImpl;
41import com.mysql.jdbc.Util;
42
43public class SuspendableXAConnection extends MysqlPooledConnection implements
44XAConnection, XAResource {
45
46        private static final Constructor<?> JDBC_4_XA_CONNECTION_WRAPPER_CTOR;
47
48        static {
49                if (Util.isJdbc4()) {
50                        try {
51                                JDBC_4_XA_CONNECTION_WRAPPER_CTOR = Class.forName(
52                                                "com.mysql.jdbc.jdbc2.optional.JDBC4SuspendableXAConnection")
53                                                .getConstructor(
54                                                                new Class[] { ConnectionImpl.class });
55                        } catch (SecurityException e) {
56                                throw new RuntimeException(e);
57                        } catch (NoSuchMethodException e) {
58                                throw new RuntimeException(e);
59                        } catch (ClassNotFoundException e) {
60                                throw new RuntimeException(e);
61                        }
62                } else {
63                        JDBC_4_XA_CONNECTION_WRAPPER_CTOR = null;
64                }
65        }
66
67        protected static SuspendableXAConnection getInstance(ConnectionImpl mysqlConnection) throws SQLException {
68                if (!Util.isJdbc4()) {
69                        return new SuspendableXAConnection(mysqlConnection);
70                }
71
72                return (SuspendableXAConnection) Util.handleNewInstance(
73                                JDBC_4_XA_CONNECTION_WRAPPER_CTOR, new Object[] {
74                                                mysqlConnection}, mysqlConnection.getExceptionInterceptor());
75        }
76       
77        public SuspendableXAConnection(ConnectionImpl connection) {
78                super(connection);
79                this.underlyingConnection = connection;
80        }
81
82        private static final Map<Xid, XAConnection> XIDS_TO_PHYSICAL_CONNECTIONS = 
83                new HashMap<Xid, XAConnection>();
84       
85        private Xid currentXid;
86       
87        private XAConnection currentXAConnection;
88        private XAResource currentXAResource;
89       
90        private ConnectionImpl underlyingConnection;
91       
92        private static synchronized XAConnection findConnectionForXid(ConnectionImpl connectionToWrap, Xid xid) 
93                throws SQLException {
94                // TODO: check for same GTRID, but different BQUALs...MySQL doesn't allow this yet
95               
96                // Note, we don't need to check for XIDs here, because MySQL itself will complain
97                // with a XAER_NOTA if need be.
98               
99                XAConnection conn = XIDS_TO_PHYSICAL_CONNECTIONS.get(xid);
100
101                if (conn == null) {
102                        conn = new MysqlXAConnection(connectionToWrap,
103                                        connectionToWrap.getLogXaCommands());
104                        XIDS_TO_PHYSICAL_CONNECTIONS.put(xid, conn);
105                }
106               
107                return conn;
108        }
109       
110        private static synchronized void removeXAConnectionMapping(Xid xid) {
111                XIDS_TO_PHYSICAL_CONNECTIONS.remove(xid);
112        }
113       
114        private synchronized void switchToXid(Xid xid) throws XAException {
115                if (xid == null) {
116                        throw new XAException();
117                }
118               
119                try {
120                        if (!xid.equals(this.currentXid)) {
121                                XAConnection toSwitchTo = findConnectionForXid(this.underlyingConnection, xid);
122                                this.currentXAConnection = toSwitchTo;
123                                this.currentXid = xid;
124                                this.currentXAResource = toSwitchTo.getXAResource();
125                        }
126                } catch (SQLException sqlEx) {
127                        throw new XAException();
128                }
129        }
130       
131        public XAResource getXAResource() throws SQLException {
132                return this;
133        }
134
135        public void commit(Xid xid, boolean arg1) throws XAException {
136                switchToXid(xid);
137                this.currentXAResource.commit(xid, arg1);
138                removeXAConnectionMapping(xid);
139        }
140
141        public void end(Xid xid, int arg1) throws XAException {
142                switchToXid(xid);
143                this.currentXAResource.end(xid, arg1);
144        }
145
146        public void forget(Xid xid) throws XAException {
147                switchToXid(xid);
148                this.currentXAResource.forget(xid);
149                // remove?
150                removeXAConnectionMapping(xid);
151        }
152
153        public int getTransactionTimeout() throws XAException {
154                return 0;
155        }
156
157        public boolean isSameRM(XAResource xaRes) throws XAException {
158                return xaRes == this;
159        }
160
161        public int prepare(Xid xid) throws XAException {
162                switchToXid(xid);
163                return this.currentXAResource.prepare(xid);
164        }
165
166        public Xid[] recover(int flag) throws XAException {
167                return MysqlXAConnection.recover(this.underlyingConnection, flag);
168        }
169
170        public void rollback(Xid xid) throws XAException {
171                switchToXid(xid);
172                this.currentXAResource.rollback(xid);
173                removeXAConnectionMapping(xid);
174        }
175
176        public boolean setTransactionTimeout(int arg0) throws XAException {
177                return false;
178        }
179
180        public void start(Xid xid, int arg1) throws XAException {
181                switchToXid(xid);
182               
183                if (arg1 != XAResource.TMJOIN) {
184                        this.currentXAResource.start(xid, arg1);
185                       
186                        return;
187                }
188               
189                //
190                // Emulate join, by using resume on the same physical connection
191                //
192               
193                this.currentXAResource.start(xid, XAResource.TMRESUME);
194        }
195
196        public synchronized java.sql.Connection getConnection() throws SQLException {
197                if (this.currentXAConnection == null) {
198                        return getConnection(false, true);
199                }
200                       
201                return this.currentXAConnection.getConnection();
202        }
203
204        public void close() throws SQLException {
205                if (this.currentXAConnection == null) {
206                        super.close();
207                } else {
208                        removeXAConnectionMapping(this.currentXid);
209                        this.currentXAConnection.close();
210                }
211        }
212}
Note: See TracBrowser for help on using the repository browser.