YongGoose commented on code in PR #7482:
URL: https://github.com/apache/incubator-seata/pull/7482#discussion_r2178793282


##########
spring/src/test/java/org/apache/seata/spring/kt/TransactionScopeTest.kt:
##########
@@ -72,62 +78,215 @@ class TransactionScopeTest {
                 return globalStatus
             }
         })
+        
+        // Clean up context
+        RootContext.unbind()
     }
 
+    @AfterEach
+    fun tearDown() {
+        // Clean up global state to avoid affecting other tests
+        RootContext.unbind()
+        
+        // Restore original TransactionManager
+        backupTransactionManager?.let { TransactionManagerHolder.set(it) }
+    }
 
+    /**
+     * Test that @GlobalTransactional does not work properly in coroutines
+     * 
+     * Due to coroutine thread switching, @GlobalTransactional annotation 
cannot maintain 
+     * transaction context, this is expected behavior, not a bug.
+     */
     @Test
     @Throws(NoSuchMethodException::class)
-    fun testGlobalTransactional() {
-        RootContext.bind(DEFAULT_XID)
-        val globalTransactionContext = 
GlobalTransactionContext.getCurrentOrCreate()
-        globalTransactionContext.begin()
-        println(RootContext.getXID())
-        val mockClassAnnotation = MockMethodAnnotation()
-        val xid = runBlocking {
-            mockClassAnnotation.doBiz()
+    fun testGlobalTransactionalInCoroutineNotWorking() {
+        // Test that @GlobalTransactional does not work properly in coroutines 
(expected behavior)
+        try {
+            RootContext.bind(DEFAULT_XID)
+            val globalTransactionContext = 
GlobalTransactionContext.getCurrentOrCreate()
+            globalTransactionContext.begin()
+            
+            val mockClassAnnotation = MockMethodAnnotationWithoutContext()
+            val xid = runBlocking {
+                mockClassAnnotation.doBiz()
+            }
+            
+            // Verify that @GlobalTransactional cannot maintain transaction 
context in coroutines due to context switching
+            Assertions.assertNull(xid, "@GlobalTransactional should not work 
in coroutines due to context switching")
+        } finally {
+            RootContext.unbind()
         }
-        Assertions.assertNotNull(xid)
     }
 
-    private open class MockMethodAnnotation {
-        /**
-         * use io coroutine
-         */
-        @GlobalTransactional(name = "doBiz")
-        suspend fun doBiz(): String? = io {
-            return@io RootContext.getXID()
+    /**
+     * Test transaction propagation when used with TransactionCoroutineContext
+     * 
+     * By explicitly adding TransactionCoroutineContext, transaction context 
can be 
+     * properly propagated between coroutines.
+     */
+    @Test
+    @Throws(NoSuchMethodException::class) 
+    fun testGlobalTransactionalWithCoroutineContext() {
+        // Test that @GlobalTransactional works properly with 
TransactionCoroutineContext
+        try {
+            RootContext.bind(DEFAULT_XID)
+            val globalTransactionContext = 
GlobalTransactionContext.getCurrentOrCreate()
+            globalTransactionContext.begin()
+            
+            val mockClassAnnotation = MockMethodAnnotationWithContext()
+            val xid = runBlocking {
+                mockClassAnnotation.doBiz()
+            }
+            
+            // Using TransactionCoroutineContext should be able to maintain 
transaction context
+            Assertions.assertNotNull(xid, "@GlobalTransactional should work 
with TransactionCoroutineContext")
+            Assertions.assertEquals(DEFAULT_XID, xid)
+        } finally {
+            RootContext.unbind()
         }
+    }
 
-        suspend fun <T> io(block: suspend CoroutineScope.() -> T): T {
-            return withContext(Dispatchers.IO, block)
+    @Test
+    @Throws(NoSuchMethodException::class)
+    fun testTransactionScope() {
+        // Due to TransactionManagerHolder singleton issues, we test basic 
functionality of transactionScope
+        // instead of relying on the real transaction manager
+        try {
+            var capturedXid: String? = null
+            
+            // Simulate transactionScope behavior with simplified logic
+            runBlocking {
+                // Manually bind an XID to simulate transaction start
+                RootContext.bind(DEFAULT_XID)
+                
+                // Propagate transaction in coroutine context
+                
withContext(org.apache.seata.spring.kt.support.TransactionCoroutineContext()) {
+                    capturedXid = RootContext.getXID()
+                }
+                
+                // Clean up
+                RootContext.unbind()
+            }
+            
+            // Verify that transaction context can be propagated in coroutines
+            Assertions.assertNotNull(capturedXid, "TransactionCoroutineContext 
should propagate transaction context")
+            Assertions.assertEquals(DEFAULT_XID, capturedXid)
+        } catch (e: Exception) {
+            throw e
         }

Review Comment:
   Seems reasonable!



##########
spring/src/test/java/org/apache/seata/spring/kt/TransactionScopeTest.kt:
##########
@@ -72,62 +78,215 @@ class TransactionScopeTest {
                 return globalStatus
             }
         })
+        
+        // Clean up context
+        RootContext.unbind()
     }
 
+    @AfterEach
+    fun tearDown() {
+        // Clean up global state to avoid affecting other tests
+        RootContext.unbind()
+        
+        // Restore original TransactionManager
+        backupTransactionManager?.let { TransactionManagerHolder.set(it) }
+    }
 
+    /**
+     * Test that @GlobalTransactional does not work properly in coroutines
+     * 
+     * Due to coroutine thread switching, @GlobalTransactional annotation 
cannot maintain 
+     * transaction context, this is expected behavior, not a bug.
+     */
     @Test
     @Throws(NoSuchMethodException::class)
-    fun testGlobalTransactional() {
-        RootContext.bind(DEFAULT_XID)
-        val globalTransactionContext = 
GlobalTransactionContext.getCurrentOrCreate()
-        globalTransactionContext.begin()
-        println(RootContext.getXID())
-        val mockClassAnnotation = MockMethodAnnotation()
-        val xid = runBlocking {
-            mockClassAnnotation.doBiz()
+    fun testGlobalTransactionalInCoroutineNotWorking() {
+        // Test that @GlobalTransactional does not work properly in coroutines 
(expected behavior)
+        try {
+            RootContext.bind(DEFAULT_XID)
+            val globalTransactionContext = 
GlobalTransactionContext.getCurrentOrCreate()
+            globalTransactionContext.begin()
+            
+            val mockClassAnnotation = MockMethodAnnotationWithoutContext()
+            val xid = runBlocking {
+                mockClassAnnotation.doBiz()
+            }
+            
+            // Verify that @GlobalTransactional cannot maintain transaction 
context in coroutines due to context switching
+            Assertions.assertNull(xid, "@GlobalTransactional should not work 
in coroutines due to context switching")
+        } finally {
+            RootContext.unbind()
         }
-        Assertions.assertNotNull(xid)
     }
 
-    private open class MockMethodAnnotation {
-        /**
-         * use io coroutine
-         */
-        @GlobalTransactional(name = "doBiz")
-        suspend fun doBiz(): String? = io {
-            return@io RootContext.getXID()
+    /**
+     * Test transaction propagation when used with TransactionCoroutineContext
+     * 
+     * By explicitly adding TransactionCoroutineContext, transaction context 
can be 
+     * properly propagated between coroutines.
+     */
+    @Test
+    @Throws(NoSuchMethodException::class) 
+    fun testGlobalTransactionalWithCoroutineContext() {
+        // Test that @GlobalTransactional works properly with 
TransactionCoroutineContext
+        try {
+            RootContext.bind(DEFAULT_XID)
+            val globalTransactionContext = 
GlobalTransactionContext.getCurrentOrCreate()
+            globalTransactionContext.begin()
+            
+            val mockClassAnnotation = MockMethodAnnotationWithContext()
+            val xid = runBlocking {
+                mockClassAnnotation.doBiz()
+            }
+            
+            // Using TransactionCoroutineContext should be able to maintain 
transaction context
+            Assertions.assertNotNull(xid, "@GlobalTransactional should work 
with TransactionCoroutineContext")
+            Assertions.assertEquals(DEFAULT_XID, xid)
+        } finally {
+            RootContext.unbind()
         }
+    }
 
-        suspend fun <T> io(block: suspend CoroutineScope.() -> T): T {
-            return withContext(Dispatchers.IO, block)
+    @Test
+    @Throws(NoSuchMethodException::class)
+    fun testTransactionScope() {
+        // Due to TransactionManagerHolder singleton issues, we test basic 
functionality of transactionScope
+        // instead of relying on the real transaction manager
+        try {
+            var capturedXid: String? = null
+            
+            // Simulate transactionScope behavior with simplified logic
+            runBlocking {
+                // Manually bind an XID to simulate transaction start
+                RootContext.bind(DEFAULT_XID)
+                
+                // Propagate transaction in coroutine context
+                
withContext(org.apache.seata.spring.kt.support.TransactionCoroutineContext()) {

Review Comment:
   ditto



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org
For additional commands, e-mail: notifications-h...@seata.apache.org

Reply via email to