From de61109544cdb7d3a13b89b6984e4057ce0ece20 Mon Sep 17 00:00:00 2001 From: devxb Date: Sat, 23 Mar 2024 13:20:45 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=97=B0=EA=B2=B0=EB=90=9C=20rollback?= =?UTF-8?q?=20function=EC=9D=B4=20=EC=97=86=EC=9C=BC=EB=A9=B4=20=EA=B0=80?= =?UTF-8?q?=EC=9E=A5=20=EA=B0=80=EA=B9=8C=EC=9A=B4=20=EC=83=81=EB=8B=A8=20?= =?UTF-8?q?rollback=20=EB=B6=80=ED=84=B0=20=EC=8B=9C=EC=9E=91=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../engine/AbstractOrchestrateListener.kt | 5 ++++- .../rooftop/netx/engine/OrchestrateChain.kt | 7 ++++++- .../netx/engine/OrchestratorConfigurer.kt | 13 ++++++++++++ .../rooftop/netx/engine/OrchestratorTest.kt | 21 ++++++++++++++++++- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/org/rooftop/netx/engine/AbstractOrchestrateListener.kt b/src/main/kotlin/org/rooftop/netx/engine/AbstractOrchestrateListener.kt index 0021429..e088d81 100644 --- a/src/main/kotlin/org/rooftop/netx/engine/AbstractOrchestrateListener.kt +++ b/src/main/kotlin/org/rooftop/netx/engine/AbstractOrchestrateListener.kt @@ -20,6 +20,7 @@ internal abstract class AbstractOrchestrateListener internal c var isLast: Boolean = true var isRollbackable: Boolean = false var beforeRollbackOrchestrateSequence: Int = 0 + var rollbackSequence: Int = orchestrateSequence private var nextOrchestrateListener: AbstractOrchestrateListener? = null private var nextRollbackOrchestrateListener: AbstractOrchestrateListener? = null @@ -103,10 +104,12 @@ internal abstract class AbstractOrchestrateListener internal c throwable: Throwable, orchestrateEvent: OrchestrateEvent, ) { + val rollbackOrchestrateEvent = + OrchestrateEvent(orchestrateEvent.orchestratorId, rollbackSequence, "") transactionManager.rollback( transactionId = transactionId, cause = throwable.message ?: throwable.localizedMessage, - event = orchestrateEvent + event = rollbackOrchestrateEvent ).subscribeOn(Schedulers.parallel()).subscribe() } diff --git a/src/main/kotlin/org/rooftop/netx/engine/OrchestrateChain.kt b/src/main/kotlin/org/rooftop/netx/engine/OrchestrateChain.kt index 1bb376f..bfb07b9 100644 --- a/src/main/kotlin/org/rooftop/netx/engine/OrchestrateChain.kt +++ b/src/main/kotlin/org/rooftop/netx/engine/OrchestrateChain.kt @@ -196,13 +196,18 @@ class OrchestrateChain private constructor( } private fun chainOrchestrateListeners(orchestrateListeners: List, AbstractOrchestrateListener?>>) { + var rollbackSequence = 0 for (listenerWithIdx in orchestrateListeners.withIndex()) { val isFirst = listenerWithIdx.index == 0 val isLast = listenerWithIdx.index == (orchestrateListeners.size - 1 - COMMIT_LISTENER_PREFIX) val listener = listenerWithIdx.value.first - listenerWithIdx.value.second?.let { listener.isRollbackable = true } + listenerWithIdx.value.second?.let { + listener.isRollbackable = true + rollbackSequence = it.orchestrateSequence + } + listener.rollbackSequence = rollbackSequence listener.isFirst = isFirst listener.isLast = isLast diff --git a/src/test/kotlin/org/rooftop/netx/engine/OrchestratorConfigurer.kt b/src/test/kotlin/org/rooftop/netx/engine/OrchestratorConfigurer.kt index 2e706d3..afafbd9 100644 --- a/src/test/kotlin/org/rooftop/netx/engine/OrchestratorConfigurer.kt +++ b/src/test/kotlin/org/rooftop/netx/engine/OrchestratorConfigurer.kt @@ -2,6 +2,7 @@ package org.rooftop.netx.engine import org.rooftop.netx.api.Orchestrator import org.rooftop.netx.engine.OrchestratorTest.Companion.rollbackOrchestratorResult +import org.rooftop.netx.engine.OrchestratorTest.Companion.upChainResult import org.rooftop.netx.factory.OrchestratorFactory import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @@ -92,4 +93,16 @@ class OrchestratorConfigurer( } ) } + + @Bean(name = ["upChainRollbackOrchestrator"]) + fun upChainRollbackOrchestrator(): Orchestrator { + return orchestratorFactory.create("upChainRollbackOrchestrator") + .start({ upChainResult.add("1") }, { upChainResult.add("-1") }) + .join({ upChainResult.add("2") }) + .join({ upChainResult.add("3") }, { upChainResult.add("-3") }) + .commit({ + upChainResult.add("4") + throw IllegalArgumentException("Rollback for test") + }) + } } diff --git a/src/test/kotlin/org/rooftop/netx/engine/OrchestratorTest.kt b/src/test/kotlin/org/rooftop/netx/engine/OrchestratorTest.kt index b196cc3..67ba4eb 100644 --- a/src/test/kotlin/org/rooftop/netx/engine/OrchestratorTest.kt +++ b/src/test/kotlin/org/rooftop/netx/engine/OrchestratorTest.kt @@ -9,6 +9,7 @@ import io.kotest.matchers.equals.shouldBeEqual import org.rooftop.netx.api.Orchestrator import org.rooftop.netx.meta.EnableDistributedTransaction import org.rooftop.netx.redis.RedisContainer +import org.springframework.beans.factory.annotation.Qualifier import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.TestPropertySource import java.time.Instant @@ -28,7 +29,8 @@ class OrchestratorTest( private val homeOrchestrator: Orchestrator, private val instantOrchestrator: Orchestrator, private val manyTypeOrchestrator: Orchestrator, - private val rollbackOrchestrator: Orchestrator, + @Qualifier("rollbackOrchestrator") private val rollbackOrchestrator: Orchestrator, + @Qualifier("upChainRollbackOrchestrator") private val upChainRollbackOrchestrator: Orchestrator, ) : DescribeSpec({ describe("numberOrchestrator 구현채는") { @@ -103,6 +105,22 @@ class OrchestratorTest( } } } + + describe("upStreamRollbackOrchestrator 구현채는") { + val expected = listOf("1", "2", "3", "4", "-3", "-1") + + it("호출할 rollback function이 없으면, 가장 가까운 상단의 rollback을 호출한다.") { + val result = upChainRollbackOrchestrator.transactionSync("") + + result.isSuccess shouldBeEqual false + shouldThrowWithMessage("Rollback for test") { + result.throwError() + } + eventually(5.seconds) { + upChainResult shouldBeEqual expected + } + } + } }) { data class Home( val address: String, @@ -121,5 +139,6 @@ class OrchestratorTest( companion object { val rollbackOrchestratorResult = mutableListOf() + val upChainResult = mutableListOf() } }