apache / incubator-seata

:fire: Seata is an easy-to-use, high-performance, open source distributed transaction solution.
https://seata.apache.org/
Apache License 2.0
25.17k stars 8.74k forks source link

TransactionPropagationInterceptor拦截器在请求发生异常时无法清除线程里xid #4512

Open liuyuan007 opened 2 years ago

liuyuan007 commented 2 years ago

Ⅰ. Issue Description

TransactionPropagationInterceptor拦截器在请求异常时无清除线程里的xid,而HTTP请求是通过线程池共享线程的。当下一次请求拿到未清除xid的线程时就会报错。

Ⅱ. Describe what happened

If there is an exception, please attach the exception trace:

org.springframework.transaction.TransactionSystemException: JDBC commit failed; nested exception is java.sql.SQLException: io.seata.core.exception.RmTransactionException: Response[ TransactionException[Could not found global transaction xid = 192.168.22.11:8091:252438693814513664, may be has finished.] ]\nat org.springframework.jdbc.datasource.DataSourceTransactionManager.translateException(DataSourceTransactionManager.java:435)\nat org.springframework.jdbc.support.JdbcTransactionManager.translateException(JdbcTransactionManager.java:188)\nat org.springframework.jdbc.datasource.DataSourceTransactionManager.doCommit(DataSourceTransactionManager.java:336)\nat org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)\nat org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)\nat org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654)\nat org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407)\nat org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)\nat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

Ⅲ. Describe what you expected to happen

@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { if (RootContext.inGlobalTransaction()) { XidResource.cleanXid(request.getHeader(RootContext.KEY_XID)); } } 改为: public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { if (RootContext.inGlobalTransaction()) { XidResource.cleanXid(request.getHeader(RootContext.KEY_XID)); } }

Ⅳ. How to reproduce it (as minimally and precisely as possible)

  1. 将HTTP请求线程池线程数设置为1。
  2. 请求中模拟异常请求。
  3. 查看RootContext中的xid值变化情况。

Ⅴ. Anything else we need to know?

Ⅵ. Environment:

linghengqian commented 1 month ago