diff --git a/src/main/java/com/iridium/iridiumskyblock/managers/tablemanagers/TableManager.java b/src/main/java/com/iridium/iridiumskyblock/managers/tablemanagers/TableManager.java index a1f66aee2..3e8254f3e 100644 --- a/src/main/java/com/iridium/iridiumskyblock/managers/tablemanagers/TableManager.java +++ b/src/main/java/com/iridium/iridiumskyblock/managers/tablemanagers/TableManager.java @@ -1,5 +1,6 @@ package com.iridium.iridiumskyblock.managers.tablemanagers; +import com.iridium.iridiumskyblock.IridiumSkyblock; import com.iridium.iridiumskyblock.managers.DatabaseKey; import com.iridium.iridiumteams.database.DatabaseObject; import com.j256.ormlite.dao.Dao; @@ -15,6 +16,9 @@ import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; import java.util.stream.Collectors; @@ -22,6 +26,7 @@ public class TableManager { private final ConcurrentHashMap entries = new ConcurrentHashMap<>(); private final Dao dao; private final DatabaseKey databaseKey; + private final static Lock lock = new ReentrantLock(); private final ConnectionSource connectionSource; @@ -38,29 +43,83 @@ public TableManager(DatabaseKey databaseKey, ConnectionSource connec public void save() { try { - List entryList = new ArrayList<>(entries.values()); - for (Value t : entryList) { - if (!t.isChanged()) continue; - dao.createOrUpdate(t); - t.setChanged(false); + if (!lock.tryLock(5, TimeUnit.SECONDS)) { + IridiumSkyblock.getInstance().getLogger().warning("Warning: Lock acquisition took more than 5 second in save() method."); } - dao.commit(getDatabaseConnection()); - } catch (SQLException throwables) { - throwables.printStackTrace(); + try { + List entryList = new ArrayList<>(entries.values()); + boolean modified = false; + for (Value t : entryList) { + if (!t.isChanged()) continue; + modified = true; + dao.createOrUpdate(t); + t.setChanged(false); + } + if (modified) dao.commit(getDatabaseConnection()); + } finally { + lock.unlock(); + } + } catch (InterruptedException | SQLException e) { + e.printStackTrace(); } } public void save(Value value) { try { - if (!value.isChanged()) return; - dao.createOrUpdate(value); - dao.commit(getDatabaseConnection()); - value.setChanged(false); - } catch (SQLException throwables) { - throwables.printStackTrace(); + if (!lock.tryLock(5, TimeUnit.SECONDS)) { + IridiumSkyblock.getInstance().getLogger().warning("Warning: Lock acquisition took more than 5 second in save(value) method."); + } + try { + if (!value.isChanged()) return; + dao.createOrUpdate(value); + dao.commit(getDatabaseConnection()); + value.setChanged(false); + } finally { + lock.unlock(); + } + } catch (InterruptedException | SQLException e) { + e.printStackTrace(); } } + public CompletableFuture delete(Value value) { + entries.remove(databaseKey.getKey(value)); + return CompletableFuture.runAsync(() -> { + try { + if (!lock.tryLock(5, TimeUnit.SECONDS)) { + IridiumSkyblock.getInstance().getLogger().warning("Warning: Lock acquisition took more than 5 second in delete(value) method."); + } + try { + dao.delete(value); + dao.commit(getDatabaseConnection()); + } finally { + lock.unlock(); + } + } catch (InterruptedException | SQLException e) { + e.printStackTrace(); + } + }); + } + + public CompletableFuture delete(Collection values) { + values.forEach(value -> entries.remove(databaseKey.getKey(value))); + return CompletableFuture.runAsync(() -> { + try { + if (!lock.tryLock(5, TimeUnit.SECONDS)) { + IridiumSkyblock.getInstance().getLogger().warning("Warning: Lock acquisition took more than 5 second in delete(Collection) method."); + } + try { + dao.delete(values); + dao.commit(getDatabaseConnection()); + } finally { + lock.unlock(); + } + } catch (InterruptedException | SQLException e) { + e.printStackTrace(); + } + }); + } + public void addEntry(Value value) { entries.put(databaseKey.getKey(value), value); } @@ -85,30 +144,6 @@ public Optional getEntry(Function searchFunction) return entries.values().stream().filter(searchFunction::apply).findFirst(); } - public CompletableFuture delete(Value value) { - entries.remove(databaseKey.getKey(value)); - return CompletableFuture.runAsync(() -> { - try { - dao.delete(value); - dao.commit(getDatabaseConnection()); - } catch (SQLException throwables) { - throwables.printStackTrace(); - } - }); - } - - public CompletableFuture delete(Collection values) { - values.forEach(value -> entries.remove(databaseKey.getKey(value))); - return CompletableFuture.runAsync(() -> { - try { - dao.delete(values); - dao.commit(getDatabaseConnection()); - } catch (SQLException throwables) { - throwables.printStackTrace(); - } - }); - } - private DatabaseConnection getDatabaseConnection() throws SQLException { return connectionSource.getReadWriteConnection(null); }