Skip to content

Commit c3adfa1

Browse files
committed
Select rows for ban status before batch update
Affects issues: - Fixed #4624
1 parent b2cce02 commit c3adfa1

3 files changed

Lines changed: 31 additions & 2 deletions

File tree

Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/Transaction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ private void manageFailure(SQLException statementFail) {
105105
boolean deadlocked = mySQLDeadlock || statementFail instanceof SQLTransactionRollbackException;
106106
boolean lockWaitTimeout = errorCode == 1205;
107107
boolean duplicateEntry = errorCode == 1062;
108-
if (mysqlOutdatedRead || deadlocked || duplicateEntry || lockWaitTimeout && attempts < ATTEMPT_LIMIT) {
108+
if (attempts < ATTEMPT_LIMIT && (mysqlOutdatedRead || deadlocked || duplicateEntry || lockWaitTimeout)) {
109109
executeTransaction(db); // Recurse to attempt again.
110110
return;
111111
}

Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/BatchBanStatusTransaction.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.djrapitops.plan.storage.database.transactions.events;
1818

1919
import com.djrapitops.plan.identification.ServerUUID;
20+
import com.djrapitops.plan.storage.database.DBType;
2021
import com.djrapitops.plan.storage.database.sql.building.Update;
2122
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
2223
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
@@ -30,6 +31,8 @@
3031
import java.util.List;
3132
import java.util.UUID;
3233

34+
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
35+
3336
/**
3437
* Transaction to update a player's ban status.
3538
*
@@ -53,6 +56,20 @@ protected void performOperations() {
5356
}
5457

5558
private Executable updateBanStatus() {
59+
if (dbType == DBType.MYSQL) {
60+
String selectUserIds = SELECT + UsersTable.ID +
61+
FROM + UsersTable.TABLE_NAME +
62+
WHERE + UsersTable.USER_UUID + " IN (" + nParameters(bannedPlayerUUIDs.size() + unbannedPlayerUUIDs.size()) + ")";
63+
List<Integer> userIds = query(db -> db.queryList(selectUserIds, set -> set.getInt(UsersTable.ID), bannedPlayerUUIDs, unbannedPlayerUUIDs));
64+
65+
String selectRowsToLock = SELECT + UserInfoTable.ID +
66+
FROM + UserInfoTable.TABLE_NAME +
67+
WHERE + UserInfoTable.USER_ID + " IN (" + nParameters(userIds.size()) + ")" +
68+
AND + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
69+
lockForUpdate();
70+
query(db -> db.queryList(selectRowsToLock, set -> set.getInt(UserInfoTable.ID), userIds, serverUUID));
71+
}
72+
5673
String sql = Update.values(UserInfoTable.TABLE_NAME, UserInfoTable.BANNED)
5774
.where(UserInfoTable.USER_ID + "=" + UsersTable.SELECT_USER_ID)
5875
.and(UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID)

Plan/common/src/test/java/com/djrapitops/plan/storage/database/queries/UserInfoQueriesTest.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ default void userInfoTableStoresCorrectUserInformation() {
4949
assertEquals(expected, userInfo);
5050
}
5151

52-
5352
@Test
5453
default void userInfoTableUpdatesBanStatus() {
5554
db().executeTransaction(new StoreServerPlayerTransaction(playerUUID, () -> TestConstants.REGISTER_TIME,
@@ -63,6 +62,19 @@ default void userInfoTableUpdatesBanStatus() {
6362
assertEquals(expected, userInfo);
6463
}
6564

65+
@Test
66+
default void userInfoTableUpdatesBanStatusBatch() {
67+
db().executeTransaction(new StoreServerPlayerTransaction(playerUUID, () -> TestConstants.REGISTER_TIME,
68+
TestConstants.PLAYER_ONE_NAME, serverUUID(), TestConstants.GET_PLAYER_HOSTNAME));
69+
70+
db().executeTransaction(new BatchBanStatusTransaction(List.of(playerUUID), List.of(), serverUUID()));
71+
72+
Set<UserInfo> userInfo = db().query(UserInfoQueries.fetchUserInformationOfUser(playerUUID));
73+
Set<UserInfo> expected = Collections.singleton(new UserInfo(playerUUID, serverUUID(), TestConstants.REGISTER_TIME, false, TestConstants.GET_PLAYER_HOSTNAME.get(), true));
74+
75+
assertEquals(expected, userInfo);
76+
}
77+
6678
@Test
6779
default void userInfoTableUpdatesOperatorStatus() {
6880
db().executeTransaction(new StoreServerPlayerTransaction(playerUUID, () -> TestConstants.REGISTER_TIME,

0 commit comments

Comments
 (0)