~pbms-core/pbms/async_read

« back to all changes in this revision

Viewing changes to mybs/java/src/com/mysql/jdbc/ReplicationConnection.java

  • Committer: paul-mccullagh
  • Date: 2008-03-26 11:35:17 UTC
  • Revision ID: paul-mccullagh-afb1610c21464a577ae428d72fc725eb986c05a5
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 Copyright (C) 2004 MySQL AB
 
3
 
 
4
 This program is free software; you can redistribute it and/or modify
 
5
 it under the terms of version 2 of the GNU General Public License as 
 
6
 published by the Free Software Foundation.
 
7
 
 
8
 There are special exceptions to the terms and conditions of the GPL 
 
9
 as it is applied to this software. View the full text of the 
 
10
 exception in file EXCEPTIONS-CONNECTOR-J in the directory of this 
 
11
 software distribution.
 
12
 
 
13
 This program is distributed in the hope that it will be useful,
 
14
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 GNU General Public License for more details.
 
17
 
 
18
 You should have received a copy of the GNU General Public License
 
19
 along with this program; if not, write to the Free Software
 
20
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
 */
 
22
package com.mysql.jdbc;
 
23
 
 
24
import java.sql.CallableStatement;
 
25
import java.sql.DatabaseMetaData;
 
26
import java.sql.PreparedStatement;
 
27
import java.sql.SQLException;
 
28
import java.sql.SQLWarning;
 
29
import java.sql.Savepoint;
 
30
import java.sql.Statement;
 
31
import java.util.Map;
 
32
import java.util.Properties;
 
33
 
 
34
/**
 
35
 * Connection that opens two connections, one two a replication master, and
 
36
 * another to one or more slaves, and decides to use master when the connection
 
37
 * is not read-only, and use slave(s) when the connection is read-only.
 
38
 * 
 
39
 * @version $Id: ReplicationConnection.java,v 1.1.2.1 2005/05/13 18:58:38
 
40
 *          mmatthews Exp $
 
41
 */
 
42
public class ReplicationConnection implements java.sql.Connection {
 
43
        private Connection currentConnection;
 
44
 
 
45
        private Connection masterConnection;
 
46
 
 
47
        private Connection slavesConnection;
 
48
 
 
49
        public ReplicationConnection(Properties masterProperties,
 
50
                        Properties slaveProperties) throws SQLException {
 
51
                Driver driver = new Driver();
 
52
 
 
53
                StringBuffer masterUrl = new StringBuffer("jdbc:mysql://");
 
54
        StringBuffer slaveUrl = new StringBuffer("jdbc:mysql://");
 
55
 
 
56
        String masterHost = masterProperties
 
57
                .getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY);
 
58
        
 
59
        if (masterHost != null) {
 
60
                masterUrl.append(masterHost);
 
61
        }
 
62
 
 
63
        String slaveHost = slaveProperties
 
64
                .getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY);
 
65
                
 
66
        if (slaveHost != null) {
 
67
                slaveUrl.append(slaveHost);
 
68
        }
 
69
        
 
70
        String masterDb = masterProperties
 
71
                .getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY);
 
72
 
 
73
        masterUrl.append("/");
 
74
        
 
75
        if (masterDb != null) {
 
76
                masterUrl.append(masterDb);
 
77
        }
 
78
        
 
79
        String slaveDb = slaveProperties
 
80
                .getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY);
 
81
        
 
82
        slaveUrl.append("/");
 
83
        
 
84
        if (slaveDb != null) {
 
85
                slaveUrl.append(slaveDb);
 
86
        }
 
87
        
 
88
        this.masterConnection = (com.mysql.jdbc.Connection) driver.connect(
 
89
                masterUrl.toString(), masterProperties);
 
90
        this.slavesConnection = (com.mysql.jdbc.Connection) driver.connect(
 
91
                slaveUrl.toString(), slaveProperties);
 
92
        
 
93
                this.currentConnection = this.masterConnection;
 
94
        }
 
95
 
 
96
        /*
 
97
         * (non-Javadoc)
 
98
         * 
 
99
         * @see java.sql.Connection#clearWarnings()
 
100
         */
 
101
        public synchronized void clearWarnings() throws SQLException {
 
102
                this.currentConnection.clearWarnings();
 
103
        }
 
104
 
 
105
        /*
 
106
         * (non-Javadoc)
 
107
         * 
 
108
         * @see java.sql.Connection#close()
 
109
         */
 
110
        public synchronized void close() throws SQLException {
 
111
                this.masterConnection.close();
 
112
                this.slavesConnection.close();
 
113
        }
 
114
 
 
115
        /*
 
116
         * (non-Javadoc)
 
117
         * 
 
118
         * @see java.sql.Connection#commit()
 
119
         */
 
120
        public synchronized void commit() throws SQLException {
 
121
                this.currentConnection.commit();
 
122
        }
 
123
 
 
124
        /*
 
125
         * (non-Javadoc)
 
126
         * 
 
127
         * @see java.sql.Connection#createStatement()
 
128
         */
 
129
        public Statement createStatement() throws SQLException {
 
130
                return this.currentConnection.createStatement();
 
131
        }
 
132
 
 
133
        /*
 
134
         * (non-Javadoc)
 
135
         * 
 
136
         * @see java.sql.Connection#createStatement(int, int)
 
137
         */
 
138
        public synchronized Statement createStatement(int resultSetType,
 
139
                        int resultSetConcurrency) throws SQLException {
 
140
                return this.currentConnection.createStatement(resultSetType,
 
141
                                resultSetConcurrency);
 
142
        }
 
143
 
 
144
        /*
 
145
         * (non-Javadoc)
 
146
         * 
 
147
         * @see java.sql.Connection#createStatement(int, int, int)
 
148
         */
 
149
        public synchronized Statement createStatement(int resultSetType,
 
150
                        int resultSetConcurrency, int resultSetHoldability)
 
151
                        throws SQLException {
 
152
                return this.currentConnection.createStatement(resultSetType,
 
153
                                resultSetConcurrency, resultSetHoldability);
 
154
        }
 
155
 
 
156
        /*
 
157
         * (non-Javadoc)
 
158
         * 
 
159
         * @see java.sql.Connection#getAutoCommit()
 
160
         */
 
161
        public synchronized boolean getAutoCommit() throws SQLException {
 
162
                return this.currentConnection.getAutoCommit();
 
163
        }
 
164
 
 
165
        /*
 
166
         * (non-Javadoc)
 
167
         * 
 
168
         * @see java.sql.Connection#getCatalog()
 
169
         */
 
170
        public synchronized String getCatalog() throws SQLException {
 
171
                return this.currentConnection.getCatalog();
 
172
        }
 
173
 
 
174
        public synchronized Connection getCurrentConnection() {
 
175
                return this.currentConnection;
 
176
        }
 
177
 
 
178
        /*
 
179
         * (non-Javadoc)
 
180
         * 
 
181
         * @see java.sql.Connection#getHoldability()
 
182
         */
 
183
        public synchronized int getHoldability() throws SQLException {
 
184
                return this.currentConnection.getHoldability();
 
185
        }
 
186
 
 
187
        public synchronized Connection getMasterConnection() {
 
188
                return this.masterConnection;
 
189
        }
 
190
 
 
191
        /*
 
192
         * (non-Javadoc)
 
193
         * 
 
194
         * @see java.sql.Connection#getMetaData()
 
195
         */
 
196
        public synchronized DatabaseMetaData getMetaData() throws SQLException {
 
197
                return this.currentConnection.getMetaData();
 
198
        }
 
199
 
 
200
        public synchronized Connection getSlavesConnection() {
 
201
                return this.slavesConnection;
 
202
        }
 
203
 
 
204
        /*
 
205
         * (non-Javadoc)
 
206
         * 
 
207
         * @see java.sql.Connection#getTransactionIsolation()
 
208
         */
 
209
        public synchronized int getTransactionIsolation() throws SQLException {
 
210
                return this.currentConnection.getTransactionIsolation();
 
211
        }
 
212
 
 
213
        /*
 
214
         * (non-Javadoc)
 
215
         * 
 
216
         * @see java.sql.Connection#getTypeMap()
 
217
         */
 
218
        public synchronized Map getTypeMap() throws SQLException {
 
219
                return this.currentConnection.getTypeMap();
 
220
        }
 
221
 
 
222
        /*
 
223
         * (non-Javadoc)
 
224
         * 
 
225
         * @see java.sql.Connection#getWarnings()
 
226
         */
 
227
        public synchronized SQLWarning getWarnings() throws SQLException {
 
228
                return this.currentConnection.getWarnings();
 
229
        }
 
230
 
 
231
        /*
 
232
         * (non-Javadoc)
 
233
         * 
 
234
         * @see java.sql.Connection#isClosed()
 
235
         */
 
236
        public synchronized boolean isClosed() throws SQLException {
 
237
                return this.currentConnection.isClosed();
 
238
        }
 
239
 
 
240
        /*
 
241
         * (non-Javadoc)
 
242
         * 
 
243
         * @see java.sql.Connection#isReadOnly()
 
244
         */
 
245
        public synchronized boolean isReadOnly() throws SQLException {
 
246
                return this.currentConnection == this.slavesConnection;
 
247
        }
 
248
 
 
249
        /*
 
250
         * (non-Javadoc)
 
251
         * 
 
252
         * @see java.sql.Connection#nativeSQL(java.lang.String)
 
253
         */
 
254
        public synchronized String nativeSQL(String sql) throws SQLException {
 
255
                return this.currentConnection.nativeSQL(sql);
 
256
        }
 
257
 
 
258
        /*
 
259
         * (non-Javadoc)
 
260
         * 
 
261
         * @see java.sql.Connection#prepareCall(java.lang.String)
 
262
         */
 
263
        public CallableStatement prepareCall(String sql) throws SQLException {
 
264
                return this.currentConnection.prepareCall(sql);
 
265
        }
 
266
 
 
267
        /*
 
268
         * (non-Javadoc)
 
269
         * 
 
270
         * @see java.sql.Connection#prepareCall(java.lang.String, int, int)
 
271
         */
 
272
        public synchronized CallableStatement prepareCall(String sql,
 
273
                        int resultSetType, int resultSetConcurrency) throws SQLException {
 
274
                return this.currentConnection.prepareCall(sql, resultSetType,
 
275
                                resultSetConcurrency);
 
276
        }
 
277
 
 
278
        /*
 
279
         * (non-Javadoc)
 
280
         * 
 
281
         * @see java.sql.Connection#prepareCall(java.lang.String, int, int, int)
 
282
         */
 
283
        public synchronized CallableStatement prepareCall(String sql,
 
284
                        int resultSetType, int resultSetConcurrency,
 
285
                        int resultSetHoldability) throws SQLException {
 
286
                return this.currentConnection.prepareCall(sql, resultSetType,
 
287
                                resultSetConcurrency, resultSetHoldability);
 
288
        }
 
289
 
 
290
        /*
 
291
         * (non-Javadoc)
 
292
         * 
 
293
         * @see java.sql.Connection#prepareStatement(java.lang.String)
 
294
         */
 
295
        public PreparedStatement prepareStatement(String sql) throws SQLException {
 
296
                return this.currentConnection.prepareStatement(sql);
 
297
        }
 
298
 
 
299
        /*
 
300
         * (non-Javadoc)
 
301
         * 
 
302
         * @see java.sql.Connection#prepareStatement(java.lang.String, int)
 
303
         */
 
304
        public synchronized PreparedStatement prepareStatement(String sql,
 
305
                        int autoGeneratedKeys) throws SQLException {
 
306
                return this.currentConnection.prepareStatement(sql, autoGeneratedKeys);
 
307
        }
 
308
 
 
309
        /*
 
310
         * (non-Javadoc)
 
311
         * 
 
312
         * @see java.sql.Connection#prepareStatement(java.lang.String, int, int)
 
313
         */
 
314
        public synchronized PreparedStatement prepareStatement(String sql,
 
315
                        int resultSetType, int resultSetConcurrency) throws SQLException {
 
316
                return this.currentConnection.prepareStatement(sql, resultSetType,
 
317
                                resultSetConcurrency);
 
318
        }
 
319
 
 
320
        /*
 
321
         * (non-Javadoc)
 
322
         * 
 
323
         * @see java.sql.Connection#prepareStatement(java.lang.String, int, int,
 
324
         *      int)
 
325
         */
 
326
        public synchronized PreparedStatement prepareStatement(String sql,
 
327
                        int resultSetType, int resultSetConcurrency,
 
328
                        int resultSetHoldability) throws SQLException {
 
329
                return this.currentConnection.prepareStatement(sql, resultSetType,
 
330
                                resultSetConcurrency, resultSetHoldability);
 
331
        }
 
332
 
 
333
        /*
 
334
         * (non-Javadoc)
 
335
         * 
 
336
         * @see java.sql.Connection#prepareStatement(java.lang.String, int[])
 
337
         */
 
338
        public synchronized PreparedStatement prepareStatement(String sql,
 
339
                        int[] columnIndexes) throws SQLException {
 
340
                return this.currentConnection.prepareStatement(sql, columnIndexes);
 
341
        }
 
342
 
 
343
        /*
 
344
         * (non-Javadoc)
 
345
         * 
 
346
         * @see java.sql.Connection#prepareStatement(java.lang.String,
 
347
         *      java.lang.String[])
 
348
         */
 
349
        public synchronized PreparedStatement prepareStatement(String sql,
 
350
                        String[] columnNames) throws SQLException {
 
351
                return this.currentConnection.prepareStatement(sql, columnNames);
 
352
        }
 
353
 
 
354
        /*
 
355
         * (non-Javadoc)
 
356
         * 
 
357
         * @see java.sql.Connection#releaseSavepoint(java.sql.Savepoint)
 
358
         */
 
359
        public synchronized void releaseSavepoint(Savepoint savepoint)
 
360
                        throws SQLException {
 
361
                this.currentConnection.releaseSavepoint(savepoint);
 
362
        }
 
363
 
 
364
        /*
 
365
         * (non-Javadoc)
 
366
         * 
 
367
         * @see java.sql.Connection#rollback()
 
368
         */
 
369
        public synchronized void rollback() throws SQLException {
 
370
                this.currentConnection.rollback();
 
371
        }
 
372
 
 
373
        /*
 
374
         * (non-Javadoc)
 
375
         * 
 
376
         * @see java.sql.Connection#rollback(java.sql.Savepoint)
 
377
         */
 
378
        public synchronized void rollback(Savepoint savepoint) throws SQLException {
 
379
                this.currentConnection.rollback(savepoint);
 
380
        }
 
381
 
 
382
        /*
 
383
         * (non-Javadoc)
 
384
         * 
 
385
         * @see java.sql.Connection#setAutoCommit(boolean)
 
386
         */
 
387
        public synchronized void setAutoCommit(boolean autoCommit)
 
388
                        throws SQLException {
 
389
                this.currentConnection.setAutoCommit(autoCommit);
 
390
        }
 
391
 
 
392
        /*
 
393
         * (non-Javadoc)
 
394
         * 
 
395
         * @see java.sql.Connection#setCatalog(java.lang.String)
 
396
         */
 
397
        public synchronized void setCatalog(String catalog) throws SQLException {
 
398
                this.currentConnection.setCatalog(catalog);
 
399
        }
 
400
 
 
401
        /*
 
402
         * (non-Javadoc)
 
403
         * 
 
404
         * @see java.sql.Connection#setHoldability(int)
 
405
         */
 
406
        public synchronized void setHoldability(int holdability)
 
407
                        throws SQLException {
 
408
                this.currentConnection.setHoldability(holdability);
 
409
        }
 
410
 
 
411
        /*
 
412
         * (non-Javadoc)
 
413
         * 
 
414
         * @see java.sql.Connection#setReadOnly(boolean)
 
415
         */
 
416
        public synchronized void setReadOnly(boolean readOnly) throws SQLException {
 
417
                if (readOnly) {
 
418
                        if (currentConnection != slavesConnection) {
 
419
                                switchToSlavesConnection();
 
420
                        }
 
421
                } else {
 
422
                        if (currentConnection != masterConnection) {
 
423
                                switchToMasterConnection();
 
424
                        }
 
425
                }
 
426
        }
 
427
 
 
428
        /*
 
429
         * (non-Javadoc)
 
430
         * 
 
431
         * @see java.sql.Connection#setSavepoint()
 
432
         */
 
433
        public synchronized Savepoint setSavepoint() throws SQLException {
 
434
                return this.currentConnection.setSavepoint();
 
435
        }
 
436
 
 
437
        /*
 
438
         * (non-Javadoc)
 
439
         * 
 
440
         * @see java.sql.Connection#setSavepoint(java.lang.String)
 
441
         */
 
442
        public synchronized Savepoint setSavepoint(String name) throws SQLException {
 
443
                return this.currentConnection.setSavepoint(name);
 
444
        }
 
445
 
 
446
        /*
 
447
         * (non-Javadoc)
 
448
         * 
 
449
         * @see java.sql.Connection#setTransactionIsolation(int)
 
450
         */
 
451
        public synchronized void setTransactionIsolation(int level)
 
452
                        throws SQLException {
 
453
                this.currentConnection.setTransactionIsolation(level);
 
454
        }
 
455
 
 
456
        // For testing
 
457
 
 
458
        /*
 
459
         * (non-Javadoc)
 
460
         * 
 
461
         * @see java.sql.Connection#setTypeMap(java.util.Map)
 
462
         */
 
463
        public synchronized void setTypeMap(Map arg0) throws SQLException {
 
464
                this.currentConnection.setTypeMap(arg0);
 
465
        }
 
466
 
 
467
        private synchronized void switchToMasterConnection() throws SQLException {
 
468
                swapConnections(this.masterConnection, this.slavesConnection);
 
469
        }
 
470
 
 
471
        private synchronized void switchToSlavesConnection() throws SQLException {
 
472
                swapConnections(this.slavesConnection, this.masterConnection);
 
473
        }
 
474
        
 
475
        /**
 
476
         * Swaps current context (catalog, autocommit and txn_isolation) from
 
477
         * sourceConnection to targetConnection, and makes targetConnection
 
478
         * the "current" connection that will be used for queries.
 
479
         * 
 
480
         * @param switchToConnection the connection to swap from
 
481
         * @param switchFromConnection the connection to swap to
 
482
         * 
 
483
         * @throws SQLException if an error occurs
 
484
         */
 
485
        private synchronized void swapConnections(Connection switchToConnection, 
 
486
                        Connection switchFromConnection) throws SQLException {
 
487
                String switchFromCatalog = switchFromConnection.getCatalog();
 
488
                String switchToCatalog = switchToConnection.getCatalog();
 
489
 
 
490
                if (switchToCatalog != null && !switchToCatalog.equals(switchFromCatalog)) {
 
491
                        switchToConnection.setCatalog(switchFromCatalog);
 
492
                } else if (switchFromCatalog != null) {
 
493
                        switchToConnection.setCatalog(switchFromCatalog);
 
494
                }
 
495
 
 
496
                boolean switchToAutoCommit = switchToConnection.getAutoCommit();
 
497
                boolean switchFromConnectionAutoCommit = switchFromConnection.getAutoCommit();
 
498
                
 
499
                if (switchFromConnectionAutoCommit != switchToAutoCommit) {
 
500
                        switchToConnection.setAutoCommit(switchFromConnectionAutoCommit);
 
501
                }
 
502
 
 
503
                int switchToIsolation = switchToConnection
 
504
                                .getTransactionIsolation();
 
505
 
 
506
                int switchFromIsolation = switchFromConnection.getTransactionIsolation();
 
507
                
 
508
                if (switchFromIsolation != switchToIsolation) {
 
509
                        switchToConnection
 
510
                                        .setTransactionIsolation(switchFromIsolation);
 
511
                }
 
512
                
 
513
                this.currentConnection = switchToConnection;
 
514
        }
 
515
}