From 1a60fdbeee4e7454d9bfb021f63dc30b03df3cab Mon Sep 17 00:00:00 2001 From: tamassoltesz Date: Fri, 27 Sep 2024 12:15:08 +0200 Subject: [PATCH] fix: fixing transaction rolled back issues with multithreaded bulk import --- .../storage/mysql/BulkImportProxyStorage.java | 5 ++--- src/main/java/io/supertokens/storage/mysql/Start.java | 9 +++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/supertokens/storage/mysql/BulkImportProxyStorage.java b/src/main/java/io/supertokens/storage/mysql/BulkImportProxyStorage.java index c7f89d4..d345a00 100644 --- a/src/main/java/io/supertokens/storage/mysql/BulkImportProxyStorage.java +++ b/src/main/java/io/supertokens/storage/mysql/BulkImportProxyStorage.java @@ -62,8 +62,7 @@ protected T startTransactionHelper(TransactionLogic logic, TransactionIso @Override public void commitTransaction(TransactionConnection con) throws StorageQueryException { - // We do not want to commit the queries when using the BulkImportProxyStorage to be able to rollback everything - // if any query fails while importing the user + } @Override @@ -86,7 +85,7 @@ public void initStorage(boolean shouldWait, List tenantIdentif public void closeConnectionForBulkImportProxyStorage() throws StorageQueryException { try { if (this.connection != null) { - this.connection.close(); + this.connection.closeForBulkImportProxyStorage(); this.connection = null; } ConnectionPool.close(this); diff --git a/src/main/java/io/supertokens/storage/mysql/Start.java b/src/main/java/io/supertokens/storage/mysql/Start.java index 93a6db2..52f8c43 100644 --- a/src/main/java/io/supertokens/storage/mysql/Start.java +++ b/src/main/java/io/supertokens/storage/mysql/Start.java @@ -26,6 +26,7 @@ import io.supertokens.pluginInterface.authRecipe.LoginMethod; import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage; import io.supertokens.pluginInterface.bulkimport.BulkImportUser; +import io.supertokens.pluginInterface.bulkimport.exceptions.BulkImportTransactionRolledBackException; import io.supertokens.pluginInterface.bulkimport.sqlStorage.BulkImportSQLStorage; import io.supertokens.pluginInterface.dashboard.DashboardSearchTags; import io.supertokens.pluginInterface.dashboard.DashboardSessionInfo; @@ -293,7 +294,15 @@ public T startTransaction(TransactionLogic logic, TransactionIsolationLev if ((e instanceof SQLTransactionRollbackException || (e.getMessage() != null && e.getMessage().toLowerCase().contains("deadlock"))) && tries < NUM_TRIES) { + try { + if(this instanceof BulkImportProxyStorage){ + throw new StorageTransactionLogicException(new BulkImportTransactionRolledBackException(e)); + // if the current instance is of BulkImportProxyStorage, that means we are doing a bulk import + // which uses nested transactions. With MySQL this retry logic doesn't going to work, we have + // to retry the whole "big" transaction, not just the innermost, current one. + // @see BulkImportTransactionRolledBackException for more explanation. + } Thread.sleep((long) (10 + (250 + Math.min(Math.pow(2, tries), 3000)) * Math.random())); } catch (InterruptedException ignored) { }