From c0d581d41ff687755fab28d734b1187e6726c2c4 Mon Sep 17 00:00:00 2001 From: md_5 Date: Fri, 5 Jul 2013 08:23:29 +1000 Subject: [PATCH] Rework SQLite again to use thread local connections - closes #492 --- .../bungee/reconnect/SQLReconnectHandler.java | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/proxy/src/main/java/net/md_5/bungee/reconnect/SQLReconnectHandler.java b/proxy/src/main/java/net/md_5/bungee/reconnect/SQLReconnectHandler.java index f1b8b8eea..13cc2fb99 100644 --- a/proxy/src/main/java/net/md_5/bungee/reconnect/SQLReconnectHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/reconnect/SQLReconnectHandler.java @@ -1,10 +1,13 @@ package net.md_5.bungee.reconnect; +import com.google.common.base.Throwables; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.HashSet; +import java.util.Set; import java.util.logging.Level; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ServerInfo; @@ -13,14 +16,31 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; public class SQLReconnectHandler extends AbstractReconnectManager { - private final Connection connection; + private final Set allConnections = new HashSet<>(); + private final ThreadLocal connectionPool = new ThreadLocal() + { + @Override + protected Connection initialValue() + { + Connection con = null; + try + { + con = DriverManager.getConnection( "jdbc:sqlite:bungee.sqlite" ); + } catch ( SQLException ex ) + { + Throwables.propagate( ex ); + } + + allConnections.add( con ); + return con; + } + }; public SQLReconnectHandler() throws ClassNotFoundException, SQLException { Class.forName( "org.sqlite.JDBC" ); - connection = DriverManager.getConnection( "jdbc:sqlite:bungee.sqlite" ); - try ( PreparedStatement ps = connection.prepareStatement( + try ( PreparedStatement ps = connectionPool.get().prepareStatement( "CREATE TABLE IF NOT EXISTS players (" + "playerId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," + "username TEXT NOT NULL UNIQUE COLLATE NOCASE," @@ -33,10 +53,10 @@ public class SQLReconnectHandler extends AbstractReconnectManager } @Override - protected synchronized ServerInfo getStoredServer(ProxiedPlayer player) + protected ServerInfo getStoredServer(ProxiedPlayer player) { String server = null; - try ( PreparedStatement ps = connection.prepareStatement( "SELECT server FROM players WHERE username = ?" ) ) + try ( PreparedStatement ps = connectionPool.get().prepareStatement( "SELECT server FROM players WHERE username = ?" ) ) { ps.setString( 1, player.getName() ); try ( ResultSet rs = ps.executeQuery() ) @@ -46,7 +66,7 @@ public class SQLReconnectHandler extends AbstractReconnectManager server = rs.getString( 1 ); } else { - try ( PreparedStatement playerUpdate = connection.prepareStatement( "INSERT INTO players( username ) VALUES( ? )" ) ) + try ( PreparedStatement playerUpdate = connectionPool.get().prepareStatement( "INSERT INTO players( username ) VALUES( ? )" ) ) { playerUpdate.setString( 1, player.getName() ); playerUpdate.executeUpdate(); @@ -62,10 +82,10 @@ public class SQLReconnectHandler extends AbstractReconnectManager } @Override - public synchronized void setServer(ProxiedPlayer player) + public void setServer(ProxiedPlayer player) { - try ( PreparedStatement ps = connection.prepareStatement( "UPDATE players SET server = ?, seen = ? WHERE username = ?" ) ) + try ( PreparedStatement ps = connectionPool.get().prepareStatement( "UPDATE players SET server = ?, seen = ? WHERE username = ?" ) ) { ps.setString( 1, player.getServer().getInfo().getName() ); ps.setInt( 2, (int) ( System.currentTimeMillis() / 1000L ) ); @@ -83,14 +103,18 @@ public class SQLReconnectHandler extends AbstractReconnectManager } @Override - public synchronized void close() + public void close() { - try + for ( Connection con : allConnections ) { - connection.close(); - } catch ( SQLException ex ) - { - ProxyServer.getInstance().getLogger().log( Level.WARNING, "Error closing SQLite connection", ex ); + try + { + con.close(); + } catch ( SQLException ex ) + { + ProxyServer.getInstance().getLogger().log( Level.WARNING, "Error closing SQLite connection", ex ); + } } + allConnections.clear(); } }