Skip to content

Commit

Permalink
Retry when failing to store join address in storeAllSessionsWithKillA…
Browse files Browse the repository at this point in the history
…ndWorldData

Another transaction may have run before this transaction that stored the same join address.

Affects issues:
- Possibly fixed #2601
  • Loading branch information
AuroraLS3 committed Sep 12, 2022
1 parent 3de1de8 commit 1e1687d
Showing 1 changed file with 16 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.djrapitops.plan.storage.database.transactions.Executable;
import org.apache.commons.lang3.StringUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
Expand Down Expand Up @@ -299,15 +300,27 @@ public void prepare(PreparedStatement statement) throws SQLException {
public static Executable storeAllSessionsWithKillAndWorldData(Collection<FinishedSession> sessions) {
return connection -> {
Set<World> existingWorlds = WorldTimesQueries.fetchWorlds().executeWithConnection(connection);
List<String> existingJoinAddresses = JoinAddressQueries.allJoinAddresses().executeWithConnection(connection);
storeAllJoinAddresses(sessions, existingJoinAddresses).execute(connection);
tryStoreAllJoinAddresses(sessions, connection, 0);
storeAllWorldNames(sessions, existingWorlds).execute(connection);
storeAllSessionsWithoutKillOrWorldData(sessions).execute(connection);
storeSessionKillData(sessions).execute(connection);
return storeSessionWorldTimeData(sessions).execute(connection);
};
}

private static void tryStoreAllJoinAddresses(Collection<FinishedSession> sessions, Connection connection, int attempt) {
try {
List<String> existingJoinAddresses = JoinAddressQueries.allJoinAddresses().executeWithConnection(connection);
storeAllJoinAddresses(sessions, existingJoinAddresses).execute(connection);
} catch (DBOpException e) {
if (e.getMessage().contains("Duplicate entry") && attempt < 3) {
tryStoreAllJoinAddresses(sessions, connection, attempt + 1);
} else {
throw e;
}
}
}

private static Executable storeAllJoinAddresses(Collection<FinishedSession> sessions, List<String> existingJoinAddresses) {
return new ExecBatchStatement(JoinAddressTable.INSERT_STATEMENT) {
@Override
Expand All @@ -318,8 +331,8 @@ public void prepare(PreparedStatement statement) {
.filter(Optional::isPresent)
.map(Optional::get)
.map(JoinAddress::getAddress)
.filter(address -> !existingJoinAddresses.contains(address))
.distinct()
.filter(address -> !existingJoinAddresses.contains(address))
.forEach(address -> {
try {
statement.setString(1, address);
Expand Down

0 comments on commit 1e1687d

Please sign in to comment.