Experimental: Lock MySQL tables so as not to break things?!

This commit is contained in:
AppleDash 2017-06-10 16:32:37 -04:00
parent dc6909af0f
commit da16d4474e
2 changed files with 7 additions and 3 deletions

View File

@ -128,10 +128,12 @@ public class EconomyStorageBackendMySQL extends EconomyStorageBackendCaching {
dbConn.executeAsyncOperation((conn) -> {
try {
ensureAccountExists(economable, conn);
conn.prepareStatement("LOCK TABLE " + dbConn.getTable("saneeconomy_balances") + " WRITE").execute();
PreparedStatement statement = dbConn.prepareStatement(conn, String.format("UPDATE `%s` SET balance = ? WHERE `unique_identifier` = ?", dbConn.getTable("saneeconomy_balances")));
statement.setDouble(1, newBalance);
statement.setString(2, economable.getUniqueIdentifier());
statement.executeUpdate();
conn.prepareStatement("UNLOCK TABLES").execute();
} catch (Exception e) {
balances.put(economable.getUniqueIdentifier(), oldBalance);
throw new RuntimeException("SQL error has occurred.", e);

View File

@ -66,24 +66,26 @@ public class MySQLConnection {
});
}
// This is a big weird because it has to account for recursion...
// This is a bit weird because it has to account for recursion...
private void doExecuteAsyncOperation(int levels, Consumer<Connection> callback) {
if (levels == 1) {
if (levels == 1) { // First level
waitForSlot();
openTransactions.incrementAndGet();
}
try (Connection conn = openConnection()) {
callback.accept(conn);
} catch (Exception e) {
if (levels > dbCredentials.getMaxRetries()) {
throw new RuntimeException("This shouldn't happen (database error)", e);
}
LOGGER.severe("An internal SQL error has occured, trying up to " + (5 - levels) + " more times...");
e.printStackTrace();
levels++;
doExecuteAsyncOperation(levels, callback);
} finally {
if (levels == 1) {
if (levels == 1) { // The recursion is done, we may have thrown an exception, maybe not - but either way we need to mark the transaction as closed.
openTransactions.decrementAndGet();
}
}