From f8d6b73c0f28ea9daeaeeeb4e3ff4fd6864a4655 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sun, 26 Sep 2021 21:46:35 +0200 Subject: [PATCH] Fix deadlock #3 :/ Signed-off-by: Lixfel --- src/de/steamwar/bungeecore/ErrorLogger.java | 3 +- src/de/steamwar/bungeecore/sql/Statement.java | 62 +++++++++++-------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/de/steamwar/bungeecore/ErrorLogger.java b/src/de/steamwar/bungeecore/ErrorLogger.java index e20a704..4bfe84c 100644 --- a/src/de/steamwar/bungeecore/ErrorLogger.java +++ b/src/de/steamwar/bungeecore/ErrorLogger.java @@ -20,6 +20,7 @@ package de.steamwar.bungeecore; import de.steamwar.bungeecore.sql.SWException; +import de.steamwar.bungeecore.sql.Statement; import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -58,7 +59,7 @@ public class ErrorLogger extends Handler { SWException.log("Bungee", "DDOS", ddosRate + ""); } return; - } else if (stacktrace.contains("ErrorLogger")) { + } else if (!Statement.connectionStable()) { return; } diff --git a/src/de/steamwar/bungeecore/sql/Statement.java b/src/de/steamwar/bungeecore/sql/Statement.java index eac7650..c37538b 100644 --- a/src/de/steamwar/bungeecore/sql/Statement.java +++ b/src/de/steamwar/bungeecore/sql/Statement.java @@ -40,39 +40,48 @@ public class Statement { Statement.user = user; Statement.password = password; try { - con = DriverManager.getConnection(url + "?autoreconnect=true", user, password); + con = DriverManager.getConnection(url + "?autoreconnect=true&useServerPrepStmts=true", user, password); } catch (SQLException e) { ProxyServer.getInstance().stop(); throw new SecurityException("Could not start SQL-Connection", e); } } - private static void reset(SQLException e) { - BungeeCore.get().getLogger().log(Level.WARNING, "SQL Exception thrown", e); + private static void reset() { close(); connect(url, user, password); try { for (Statement statement : statements) { statement.init(); } - } catch (SQLException ex) { - throw new SecurityException("Could not reprepare SQL Statements", ex); + } catch (SQLException e) { + throw new SecurityException("Could not reprepare SQL statements", e); } } public static void close() { - for (Statement statement : statements) { + synchronized (statements) { + for (Statement statement : statements) { + try { + statement.st.close(); + } catch (SQLException e) { + BungeeCore.get().getLogger().log(Level.INFO, "Could not close statement", e); + } + } + try { - statement.st.close(); + con.close(); } catch (SQLException e) { - BungeeCore.get().getLogger().log(Level.INFO, "Could not close statement", e); + BungeeCore.get().getLogger().log(Level.INFO, "Could not close SQL connection", e); } } + } + public static boolean connectionStable() { try { - con.close(); + return !con.isClosed(); } catch (SQLException e) { - BungeeCore.log("Could not close SQL-Connection", e); + return false; } } @@ -85,39 +94,38 @@ public class Statement { try { init(); } catch (SQLException e) { - reset(e); + throw new SecurityException("Could not init SQL statement", e); } } - private synchronized void init() throws SQLException { + private void init() throws SQLException { st = con.prepareStatement(sql); } T select(ResultSetUser user, Object... objects) { - return prepare(() -> { - ResultSet rs = st.executeQuery(); - T result = user.use(rs); - rs.close(); - return result; - }, objects); + synchronized (statements) { + return prepare(() -> { + ResultSet rs = st.executeQuery(); + T result = user.use(rs); + rs.close(); + return result; + }, objects); + } } void update(Object... objects) { - prepare(st::executeUpdate, objects); + synchronized (statements) { + prepare(st::executeUpdate, objects); + } } - private synchronized T prepare(SQLRunnable runnable, Object... objects) { + private T prepare(SQLRunnable runnable, Object... objects) { try { setObjects(objects); return runnable.run(); } catch (SQLException e) { - reset(e); - try { - setObjects(objects); - return runnable.run(); - } catch (SQLException ex) { - throw new SecurityException("Could not execute SQL statement", ex); - } + reset(); + throw new SecurityException("Could not execute SQL statement", e); } }