Skip to content

Commit d4675cd

Browse files
committed
解决一个事务内有多类型数据库/多个不同数据库连接有时不能同步提交/回滚;解决特定版本的 MySQL 等部分数据库重复 setAutoCommit/setTransactionIsolation 报错
1 parent c8c3b92 commit d4675cd

File tree

2 files changed

+63
-41
lines changed

2 files changed

+63
-41
lines changed

APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,10 @@ public static void verifySchema(String sch, String table) {
511511
}
512512

513513
public static String extractSchema(String sch, String table) {
514+
if (StringUtil.isEmpty(sch)) {
515+
return sch;
516+
}
517+
514518
if (table == null) {
515519
table = "Table";
516520
}

APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java

Lines changed: 59 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import java.sql.Blob;
1010
import java.sql.Clob;
1111
import java.sql.Connection;
12-
import java.util.Date;
12+
import java.util.*;
1313
import java.sql.DriverManager;
1414
import java.sql.PreparedStatement;
1515
import java.sql.ResultSet;
@@ -22,14 +22,7 @@
2222
import java.time.LocalDateTime;
2323
import java.time.Month;
2424
import java.time.Year;
25-
import java.util.ArrayList;
26-
import java.util.Arrays;
27-
import java.util.Collection;
28-
import java.util.HashMap;
29-
import java.util.List;
30-
import java.util.Map;
3125
import java.util.Map.Entry;
32-
import java.util.Set;
3326
import java.util.regex.Pattern;
3427

3528
import com.alibaba.fastjson.JSON;
@@ -1202,35 +1195,55 @@ public void setTransactionIsolation(int transactionIsolation) {
12021195
this.transactionIsolation = transactionIsolation;
12031196
}
12041197

1205-
private boolean isIsolationStatusSet = false; //已设置事务等级
1198+
protected Map<Connection, Integer> isolationMap = new LinkedHashMap<>();
12061199
@Override
12071200
public void begin(int transactionIsolation) throws SQLException {
12081201
Log.d("\n\n" + TAG, "<<<<<<<<<<<<<< TRANSACTION begin transactionIsolation = " + transactionIsolation + " >>>>>>>>>>>>>>>>>>>>>>> \n\n");
12091202
// 不做判断,如果掩盖了问题,调用层都不知道为啥事务没有提交成功
12101203
// if (connection == null || connection.isClosed()) {
12111204
// return;
12121205
// }
1213-
if (! isIsolationStatusSet) { //只设置一次Isolation等级 PG重复设置事务等级会报错
1214-
isIsolationStatusSet = true;
1215-
connection.setTransactionIsolation(transactionIsolation); // 这句导致 TDengine 驱动报错
1206+
1207+
// 将所有连接设置隔离级别,且禁止自动提交,需要以下代码来 commit/rollback
1208+
Collection<Connection> connections = connectionMap.values();
1209+
if (connections != null) {
1210+
for (Connection connection : connections) {
1211+
try {
1212+
Integer isolation = isolationMap.get(connection);
1213+
if (isolation == null || isolation != transactionIsolation) { // 只设置一次 Isolation 等级 PG 及 MySQL 某些版本重复设置事务等级会报错
1214+
isolationMap.put(connection, transactionIsolation);
1215+
1216+
connection.setTransactionIsolation(transactionIsolation); // 这句导致 TDengine 驱动报错
1217+
if (isolation == null) {
1218+
connection.setAutoCommit(false); // java.sql.SQLException: Can''t call commit when autocommit=true
1219+
}
1220+
}
1221+
}
1222+
catch (SQLException e) {
1223+
e.printStackTrace();
1224+
}
1225+
}
12161226
}
1217-
connection.setAutoCommit(false); //java.sql.SQLException: Can''t call commit when autocommit=true
12181227
}
1228+
12191229
@Override
12201230
public void rollback() throws SQLException {
12211231
Log.d("\n\n" + TAG, "<<<<<<<<<<<<<< TRANSACTION rollback >>>>>>>>>>>>>>>>>>>>>>> \n\n");
12221232
//权限校验不通过,connection 也不会生成,还是得判断 //不做判断,如果掩盖了问题,调用层都不知道为啥事务没有提交成功
1223-
if (connection == null) { // || connection.isClosed()) {
1224-
return;
1225-
}
1233+
// if (connection == null) { // || connection.isClosed()) {
1234+
// return;
1235+
// }
1236+
12261237
// 将所有连接进行回滚
12271238
Collection<Connection> connections = connectionMap.values();
1228-
12291239
if (connections != null) {
12301240
for (Connection connection : connections) {
12311241
try {
12321242
if (connection != null && connection.isClosed() == false) {
12331243
connection.rollback();
1244+
connection.setAutoCommit(true);
1245+
1246+
isolationMap.remove(connection);
12341247
}
12351248
}
12361249
catch (SQLException e) {
@@ -1239,50 +1252,56 @@ public void rollback() throws SQLException {
12391252
}
12401253
}
12411254
}
1255+
12421256
@Override
12431257
public void rollback(Savepoint savepoint) throws SQLException {
12441258
Log.d("\n\n" + TAG, "<<<<<<<<<<<<<< TRANSACTION rollback savepoint " + (savepoint == null ? "" : "!") + "= null >>>>>>>>>>>>>>>>>>>>>>> \n\n");
1245-
//权限校验不通过,connection 也不会生成,还是得判断 //不做判断,如果掩盖了问题,调用层都不知道为啥事务没有提交成功
1246-
if (connection == null) { // || connection.isClosed()) {
1259+
if (savepoint == null) {
1260+
rollback();
12471261
return;
12481262
}
1249-
1250-
if(StringUtil.isEmpty(savepoint)) {
1251-
// 将所有连接进行回滚
1252-
Collection<Connection> connections = connectionMap.values();
1253-
1254-
if (connections != null) {
1255-
for (Connection connection : connections) {
1256-
try {
1257-
if (connection != null && connection.isClosed() == false) {
1258-
connection.rollback();
1259-
}
1260-
}
1261-
catch (SQLException e) {
1262-
e.printStackTrace();
1263+
1264+
//权限校验不通过,connection 也不会生成,还是得判断 //不做判断,如果掩盖了问题,调用层都不知道为啥事务没有提交成功
1265+
// if (connection == null) { // || connection.isClosed()) {
1266+
// return;
1267+
// }
1268+
1269+
// 将所有连接进行回滚
1270+
Collection<Connection> connections = connectionMap.values();
1271+
if (connections != null) {
1272+
for (Connection connection : connections) {
1273+
try {
1274+
if (connection != null && connection.isClosed() == false) {
1275+
connection.rollback(savepoint);
1276+
connection.setAutoCommit(true);
1277+
1278+
isolationMap.remove(connection);
12631279
}
12641280
}
1281+
catch (SQLException e) {
1282+
e.printStackTrace();
1283+
}
12651284
}
1266-
} else {
1267-
connection.rollback(savepoint);
12681285
}
12691286
}
1287+
12701288
@Override
12711289
public void commit() throws SQLException {
12721290
Log.d("\n\n" + TAG, "<<<<<<<<<<<<<< TRANSACTION commit >>>>>>>>>>>>>>>>>>>>>>> \n\n");
12731291
//权限校验不通过,connection 也不会生成,还是得判断 //不做判断,如果掩盖了问题,调用层都不知道为啥事务没有提交成功
1274-
if (connection == null) { // || connection.isClosed()) {
1275-
return;
1276-
}
1292+
// if (connection == null) { // || connection.isClosed()) {
1293+
// return;
1294+
// }
12771295

12781296
// 将所有连接进行提交
12791297
Collection<Connection> connections = connectionMap.values();
1280-
12811298
if (connections != null) {
12821299
for (Connection connection : connections) {
12831300
try {
12841301
if (connection != null && connection.isClosed() == false) {
12851302
connection.commit();
1303+
1304+
isolationMap.remove(connection);
12861305
}
12871306
}
12881307
catch (SQLException e) {
@@ -1309,7 +1328,6 @@ public void close() {
13091328
}
13101329

13111330
Collection<Connection> connections = connectionMap.values();
1312-
13131331
if (connections != null) {
13141332
for (Connection connection : connections) {
13151333
try {
@@ -1334,7 +1352,7 @@ public ResultSet executeQuery(@NotNull SQLConfig config, String sql) throws Exce
13341352

13351353
Connection conn = getConnection(config);
13361354
Statement stt = conn.createStatement();
1337-
//Statement stt = config.isTDengine()
1355+
// Statement stt = config.isTDengine()
13381356
// ? conn.createStatement() // fix Presto: ResultSet: Exception: set type is TYPE_FORWARD_ONLY, Result set concurrency must be CONCUR_READ_ONLY
13391357
// : conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
13401358

0 commit comments

Comments
 (0)