From ebfe01e4c4cca0b4ae71195b80e3d73d91e717f1 Mon Sep 17 00:00:00 2001 From: Graham Date: Sat, 11 Dec 2021 20:15:22 +0000 Subject: [PATCH] Make executeOnce public Signed-off-by: Graham --- db/src/main/kotlin/org/openrs2/db/Database.kt | 9 +++- .../kotlin/org/openrs2/db/DatabaseTest.kt | 41 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/db/src/main/kotlin/org/openrs2/db/Database.kt b/db/src/main/kotlin/org/openrs2/db/Database.kt index 65251893..6ffb2828 100644 --- a/db/src/main/kotlin/org/openrs2/db/Database.kt +++ b/db/src/main/kotlin/org/openrs2/db/Database.kt @@ -79,7 +79,14 @@ public class Database( throw AssertionError() } - private fun executeOnce(transaction: Transaction): T { + /** + * Executes a [Transaction]. If the transaction fails due to deadlock, it + * is not retried. This method should therefore only be used if the + * [Transaction.execute] method has side effects. + * @param transaction the transaction. + * @return the result returned by [Transaction.execute]. + */ + public fun executeOnce(transaction: Transaction): T { dataSource.connection.use { connection -> val oldAutoCommit = connection.autoCommit connection.autoCommit = false diff --git a/db/src/test/kotlin/org/openrs2/db/DatabaseTest.kt b/db/src/test/kotlin/org/openrs2/db/DatabaseTest.kt index d32863a4..8af9b959 100644 --- a/db/src/test/kotlin/org/openrs2/db/DatabaseTest.kt +++ b/db/src/test/kotlin/org/openrs2/db/DatabaseTest.kt @@ -44,6 +44,19 @@ class DatabaseTest { assertEquals(0, elapsed) } + @Test + fun testSuccessfulOnce() { + val result = database.executeOnce { connection -> + connection.prepareStatement("VALUES 12345").use { stmt -> + val rows = stmt.executeQuery() + assertTrue(rows.next()) + return@executeOnce rows.getInt(1) + } + } + + assertEquals(12345, result) + } + @Test fun testDeadlockRetry() = runBlockingTest { var attempts = 0 @@ -68,6 +81,20 @@ class DatabaseTest { assertEquals(10, elapsed) } + @Test + fun testDeadlockOnce() { + var attempts = 0 + + assertFailsWith { + database.executeOnce { + attempts++ + throw DeadlockException() + } + } + + assertEquals(1, attempts) + } + @Test fun testDeadlockFailure() { var attempts = 0 @@ -100,6 +127,20 @@ class DatabaseTest { assertEquals(1, attempts) } + @Test + fun testNonDeadlockFailureOnce() { + var attempts = 0 + + assertFailsWith { + database.executeOnce { + attempts++ + throw TestException() + } + } + + assertEquals(1, attempts) + } + @Test fun testDeadlockCauseChain() = runBlockingTest { var attempts = 0