1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.dbcp2.managed;
18
19 import java.sql.Connection;
20 import java.sql.SQLException;
21 import java.time.Duration;
22
23 import javax.management.ObjectName;
24
25 import org.apache.commons.dbcp2.Constants;
26 import org.apache.commons.dbcp2.DelegatingPreparedStatement;
27 import org.apache.commons.dbcp2.PStmtKey;
28 import org.apache.commons.dbcp2.PoolableConnection;
29 import org.apache.commons.dbcp2.PoolableConnectionFactory;
30 import org.apache.commons.dbcp2.PoolingConnection;
31 import org.apache.commons.pool2.KeyedObjectPool;
32 import org.apache.commons.pool2.PooledObject;
33 import org.apache.commons.pool2.impl.DefaultPooledObject;
34 import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
35 import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
36
37
38
39
40
41
42 public class PoolableManagedConnectionFactory extends PoolableConnectionFactory {
43
44
45 private final TransactionRegistry transactionRegistry;
46
47
48
49
50
51
52
53
54
55 public PoolableManagedConnectionFactory(final XAConnectionFactory connFactory, final ObjectName dataSourceJmxName) {
56 super(connFactory, dataSourceJmxName);
57 this.transactionRegistry = connFactory.getTransactionRegistry();
58 }
59
60
61
62
63
64
65
66 public TransactionRegistry getTransactionRegistry() {
67 return transactionRegistry;
68 }
69
70
71
72
73
74
75
76 @SuppressWarnings("resource")
77 @Override
78 public synchronized PooledObject<PoolableConnection> makeObject() throws SQLException {
79 Connection conn = getConnectionFactory().createConnection();
80 if (conn == null) {
81 throw new IllegalStateException("Connection factory returned null from createConnection");
82 }
83 initializeConnection(conn);
84 if (getPoolStatements()) {
85 conn = new PoolingConnection(conn);
86 final GenericKeyedObjectPoolConfig<DelegatingPreparedStatement> config = new GenericKeyedObjectPoolConfig<>();
87 config.setMaxTotalPerKey(-1);
88 config.setBlockWhenExhausted(false);
89 config.setMaxWait(Duration.ZERO);
90 config.setMaxIdlePerKey(1);
91 config.setMaxTotal(getMaxOpenPreparedStatements());
92 final ObjectName dataSourceJmxName = getDataSourceJmxName();
93 final long connIndex = getConnectionIndex().getAndIncrement();
94 if (dataSourceJmxName != null) {
95 final StringBuilder base = new StringBuilder(dataSourceJmxName.toString());
96 base.append(Constants.JMX_CONNECTION_BASE_EXT);
97 base.append(connIndex);
98 config.setJmxNameBase(base.toString());
99 config.setJmxNamePrefix(Constants.JMX_STATEMENT_POOL_PREFIX);
100 } else {
101 config.setJmxEnabled(false);
102 }
103 final KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> stmtPool = new GenericKeyedObjectPool<>(
104 (PoolingConnection) conn, config);
105 ((PoolingConnection) conn).setStatementPool(stmtPool);
106 ((PoolingConnection) conn).setCacheState(getCacheState());
107 }
108 final PoolableManagedConnection pmc = new PoolableManagedConnection(transactionRegistry, conn, getPool(),
109 getDisconnectionSqlCodes(), getDisconnectionIgnoreSqlCodes(), isFastFailValidation());
110 pmc.setCacheState(getCacheState());
111 return new DefaultPooledObject<>(pmc);
112 }
113 }