annotate src/fschmidt/db/pool/PooledConnection.java @ 69:4bc1fc540265 default tip

update luan
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 05 Oct 2025 20:45:39 -0600
parents 00520880ad02
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
68
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
1 /*
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
2 Copyright (c) 2008 Franklin Schmidt <fschmidt@gmail.com>
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
3
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
4 Permission is hereby granted, free of charge, to any person obtaining a copy
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
5 of this software and associated documentation files (the "Software"), to deal
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
6 in the Software without restriction, including without limitation the rights
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
8 copies of the Software, and to permit persons to whom the Software is
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
9 furnished to do so, subject to the following conditions:
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
10
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
11 The above copyright notice and this permission notice shall be included in
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
12 all copies or substantial portions of the Software.
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
13
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
20 THE SOFTWARE.
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
21 */
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
22
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
23 package fschmidt.db.pool;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
24
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
25 import java.sql.Connection;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
26 import java.sql.SQLException;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
27 import java.sql.Statement;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
28 import java.sql.ResultSet;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
29 import java.util.List;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
30 import java.util.ArrayList;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
31 import java.util.Set;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
32 import java.util.HashSet;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
33 import org.slf4j.Logger;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
34 import org.slf4j.LoggerFactory;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
35 import fschmidt.db.DbDatabase;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
36 import fschmidt.db.DbObject;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
37 import fschmidt.db.DbKey;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
38 import fschmidt.db.DbObjectFactory;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
39 import fschmidt.db.SQLRuntimeException;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
40 import fschmidt.db.extend.DbDatabaseExt;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
41 import fschmidt.db.extend.DbTableExt;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
42 import fschmidt.db.extend.DbTransaction;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
43 import fschmidt.db.extend.DbRecordExt;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
44 import fschmidt.db.extend.FilterDatabase;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
45 import fschmidt.util.java.Stack;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
46 import fschmidt.util.java.ArrayStack;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
47
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
48
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
49 public final class PooledConnection {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
50 private static final Logger logger = LoggerFactory.getLogger(PooledConnection.class);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
51
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
52 private final Pool pool;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
53 private Connection con;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
54 private int trans = 0;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
55 final List<Runnable> beforeCommitList = new ArrayList<Runnable>();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
56 final List<Runnable> afterCommitList = new ArrayList<Runnable>();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
57 DbTransaction dbTrans = null;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
58 long lastUsed;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
59 boolean ignoreRunnablesInThisTransaction = false;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
60 private final Stack<NestedConnection> nesting = new ArrayStack<NestedConnection>();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
61 private volatile String user = null;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
62
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
63 PooledConnection(DbDatabaseImpl db)
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
64 throws SQLException
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
65 {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
66 this.pool = db.pool;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
67 this.con = db.database().getConnection();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
68 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
69
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
70 protected void finalize() throws Throwable {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
71 super.finalize();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
72 if( con == null )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
73 return;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
74 if( !nesting.isEmpty() )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
75 logger.error("connection lost from pool: opened="+nesting.size()+" trans="+trans,nesting.peek().initException);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
76 try {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
77 this.con.close();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
78 } catch(SQLException e) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
79 } finally {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
80 this.con = null;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
81 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
82 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
83
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
84 void setUser(String user) throws SQLException {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
85 if( this.user == user ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
86 /*
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
87 Statement stmt = con.createStatement();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
88 ResultSet rs = stmt.executeQuery("select CURRENT_USER");
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
89 rs.next();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
90 String s = rs.getString("CURRENT_USER");
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
91 rs.close();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
92 stmt.close();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
93 if( s.equals(user) )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
94 return;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
95 logger.error("setUser error, user should be "+user+" but is "+s,new Exception());
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
96 */
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
97 return;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
98 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
99 this.user = null;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
100 Statement stmt = con.createStatement();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
101 stmt.executeUpdate(
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
102 "set role " + user
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
103 );
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
104 stmt.close();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
105 this.user = user;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
106 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
107
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
108 Connection nest(String user) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
109 NestedConnection nc = new NestedConnection(this,user);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
110 nesting.push(nc);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
111 return nc.proxyCon;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
112 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
113
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
114 private void transOver()
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
115 throws SQLException
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
116 {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
117 con.setAutoCommit(true);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
118 trans = 0;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
119 dbTrans = null;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
120 ignoreRunnablesInThisTransaction = false;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
121 beforeCommitList.clear();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
122 afterCommitList.clear();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
123 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
124
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
125 void setAutoCommit(boolean autoCommit)
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
126 throws SQLException
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
127 {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
128 int opened = nesting.size();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
129 if( autoCommit==true ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
130 //logger.warn("setAutoCommit true not well supported");
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
131 if( trans > 0 ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
132 if( trans != opened )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
133 throw new IllegalStateException("setAutoCommit to true with unclosed connections");
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
134 transOver();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
135 return;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
136 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
137 } else if( trans == 0 ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
138 trans = opened;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
139 dbTrans = new DbTransaction();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
140 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
141 con.setAutoCommit(autoCommit);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
142 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
143
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
144 void commit()
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
145 throws SQLException
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
146 {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
147 int opened = nesting.size();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
148 if( trans != opened )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
149 throw new IllegalStateException("commit failed: trans="+trans+" opened="+opened);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
150 final int opened2 = opened;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
151 while( !beforeCommitList.isEmpty() ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
152 Runnable[] a = beforeCommitList.toArray(new Runnable[0]);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
153 beforeCommitList.clear();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
154 for( int i=0; i<a.length; i++ ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
155 a[i].run();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
156 if( opened != opened2 ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
157 logger.error("before commit opened="+opened+" opened2="+opened2+" runnable="+a[i]);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
158 opened = opened2;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
159 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
160 a[i] = null;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
161 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
162 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
163 { // for now, to catch aborted transactions
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
164 Statement stmt = con.createStatement();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
165 stmt.executeQuery("select 1");
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
166 stmt.close();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
167 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
168 con.commit();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
169 if( afterCommitList.isEmpty() ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
170 dbTrans = new DbTransaction();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
171 } else {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
172 Runnable[] a = afterCommitList.toArray(new Runnable[0]);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
173 setAutoCommit(true);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
174 for( int i=0; i<a.length; i++ ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
175 a[i].run();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
176 if( opened != opened2 ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
177 logger.error("after commit opened="+opened+" opened2="+opened2+" runnable="+a[i]);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
178 opened = opened2;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
179 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
180 a[i] = null;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
181 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
182 setAutoCommit(false);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
183 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
184 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
185
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
186 void rollback()
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
187 throws SQLException
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
188 {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
189 int opened = nesting.size();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
190 if( trans != opened )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
191 logger.warn("rollback called in nested transaction");
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
192 con.rollback();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
193 beforeCommitList.clear();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
194 afterCommitList.clear();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
195 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
196
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
197 void close(NestedConnection nestedCon)
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
198 throws SQLException
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
199 {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
200 int i = nesting.indexOf(nestedCon);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
201 if( trans==nesting.size() ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
202 if( i != trans - 1 )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
203 logger.error("closing connection outside of transaction: i="+i+" trans="+trans,new Exception(nestedCon.initException));
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
204 con.rollback(); // rollback everything since last commit
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
205 transOver();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
206 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
207 if( i < trans )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
208 logger.error("closing connection outside of transaction: i="+i+" trans="+trans,new Exception(nestedCon.initException));
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
209 nesting.remove(nestedCon);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
210 if( !nesting.isEmpty() ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
211 nesting.get(nesting.size()-1).setUser(); // best guess
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
212 return;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
213 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
214 if( trans != 0 )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
215 logger.error("trans = "+trans,new Exception());
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
216 pool.localCon.remove();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
217 if( !beforeCommitList.isEmpty() ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
218 logger.error("beforeCommitList = "+beforeCommitList,new Exception());
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
219 beforeCommitList.clear();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
220 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
221 if( !afterCommitList.isEmpty() ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
222 logger.error("afterCommitList = "+afterCommitList,new Exception());
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
223 afterCommitList.clear();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
224 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
225 lastUsed = System.currentTimeMillis();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
226 synchronized(pool) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
227 if( pool.isExpired(lastUsed) ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
228 con.close();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
229 con = null;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
230 } else {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
231 if( con.getAutoCommit() == false ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
232 logger.error("autoCommit is false at close",new Exception());
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
233 con.setAutoCommit(true);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
234 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
235 pool.stack.push(this);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
236 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
237 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
238 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
239
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
240 Connection con() {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
241 return con;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
242 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
243
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
244 boolean isInTransaction() {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
245 return dbTrans!=null;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
246 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
247
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
248 void commitTransaction() {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
249 if( !isInTransaction() )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
250 throw new IllegalStateException("commitTransaction called outside of transaction");
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
251 try {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
252 if( con.getAutoCommit()==true )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
253 throw new IllegalStateException("commitTransaction called outside of transaction");
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
254 int opened = nesting.size();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
255 if( opened < trans )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
256 throw new IllegalStateException();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
257 if( opened > trans )
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
258 throw new IllegalStateException("commitTransaction called with unclosed connections");
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
259 commit();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
260 setAutoCommit(true);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
261 } catch(SQLException e) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
262 throw new SQLRuntimeException(e);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
263 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
264 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
265
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
266 void endTransaction() {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
267 try {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
268 if( con.getAutoCommit()==false && nesting.size() > trans ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
269 logger.error("endTransaction called with unclosed connections, closing them now",new Exception(nesting.peek().initException));
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
270 while( nesting.size() > trans ) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
271 nesting.peek().close();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
272 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
273 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
274 nesting.peek().close();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
275 } catch(SQLException e) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
276 throw new SQLRuntimeException(e);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
277 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
278 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
279
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
280 void forceClose() {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
281 logger.error("connection never closed: opened="+nesting.size()+" trans="+trans+" user="+user,nesting.peek().initException);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
282 pool.localCon.remove();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
283 try {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
284 con.close();
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
285 } catch(SQLException e) {
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
286 logger.error("",e);
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
287 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
288 con = null;
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
289 }
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
290
00520880ad02 add fschmidt source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
291 }