incubator-seata icon indicating copy to clipboard operation
incubator-seata copied to clipboard

使用seata操作MySQL,两个行锁不同的事务发生死锁问题

Open Self-revolution opened this issue 1 year ago • 9 comments

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Ⅰ. Issue Description

使用seata 1.8.0操作MySQL,在更新数据前使用ID获取行锁。两个并发事务在同一个方法中通过ID获取行锁,且ID不同,并对该方法使用了@GlobalLock+@Transactional(rollbackFor = Exception.class)注解,且服务调用方还使用了@GlobalTransactional注解,结果不知为什么发生死锁。通过MySQL命令SHOW ENGINE INNODB STATUS 查看死锁日志,发生死锁的SQL似乎是@GlobalLock注解自动执行的: 事务1:SELECT id FROM locator WHERE flag_deleted = 0 AND id IN (9792, 9752) FOR UPDATE 事务2:SELECT id FROM locator WHERE flag_deleted = 0 AND id IN (116, 9753) FOR UPDATE

另一个问题是:作为临时解决方案,我尝试在本地事务外捕获这个异常,并重新执行方法,则seata报错,但事务已回滚:io.seata.rm.datasource.exec.SelectForUpdateExecutor: mysql release save point error. java.sql.SQLSyntaxErrorException: SAVEPOINT 9114eff0_9a3f_4fdf_81cb_3fa15ed63351 does not exist

Ⅱ. Describe what happened

  1. 死锁异常:
org.springframework.dao.DeadlockLoserDataAccessException: 
### Error querying database.  Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
### The error may exist in com/holo/storage/service/locator/dao/LocatorDao.java (best guess)
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT  id,code,name,group_code,nickname,description,type,container_sum,container_max,flag_occupied,flag_full_container,container_in_sum,flag_full_container_in,container_out_sum,flag_not_all_container_out,last_in_container_id,last_in_container_code,last_in_container_name,container_in_out_time,flag_target,locked_container_id,locked_container_code,locked_container_name,origin_sum,origin_container_id,origin_container_code,origin_container_name,destination_sum,destination_container_id,destination_container_code,destination_container_name,recommend_sum,recommend_max,flag_full_recommend,recommend_container_id,recommend_container_code,recommend_container_name,product_id,product_code,product_name,package_quantity_sum,product_quantity_sum,store_zone_id,store_zone_code,store_zone_name,storeroom_id,storeroom_code,storeroom_name,warehouse_id,warehouse_code,warehouse_name,logistics_center_id,logistics_center_code,logistics_center_name,purpose,flag_show,storing_type,stacking_type,full_packing_type,working_distance,in_index,out_index,shelf_row,shelf_column,shelf_big_column,shelf_layer,shelf_depth,roadway,x,y,z,xsize,ysize,zsize,volume,size_unit,weight_limit,weight_unit,capacity,percent,pre_occupation_capacity,pre_occupation_percent,pre_release_capacity,pre_release_percent,heat_degree,card_panel_number,state,flag_virtual,stacker_code,conveyor_code,agv_code,unity_type,reserved_1,reserved_2,reserved_3,reserved_4,reserved_5,extra,flag_locked,flag_enabled,flag_deleted,version,creator,creator_nickname,creation_time,updater,updater_nickname,update_time  FROM locator  WHERE flag_deleted=0     AND (id IN (?,?)) FOR UPDATE
### Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
; Deadlock found when trying to get lock; try restarting transaction
	at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:278) ~[spring-jdbc-6.1.2.jar!/:6.1.2]
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:107) ~[spring-jdbc-6.1.2.jar!/:6.1.2]
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:92) ~[mybatis-spring-3.0.3.jar!/:3.0.3]
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) ~[mybatis-spring-3.0.3.jar!/:3.0.3]
	at jdk.proxy2/jdk.proxy2.$Proxy153.selectList(Unknown Source) ~[?:?]
	at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) ~[mybatis-spring-3.0.3.jar!/:3.0.3]
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:164) ~[mybatis-plus-core-3.5.5.jar!/:3.5.5]
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:77) ~[mybatis-plus-core-3.5.5.jar!/:3.5.5]
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:152) ~[mybatis-plus-core-3.5.5.jar!/:3.5.5]
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89) ~[mybatis-plus-core-3.5.5.jar!/:3.5.5]
	at jdk.proxy2/jdk.proxy2.$Proxy171.selectList(Unknown Source) ~[?:?]
	at com.holo.common.core.service.HoloBaseServiceImpl.listByIdsForUpdate(HoloBaseServiceImpl.java:127) ~[holo-common-core-1.0.jar!/:?]
	at com.holo.storage.service.locator.service.impl.LocatorServiceImpl.updateBatch(LocatorServiceImpl.java:353) ~[!/:?]
	at com.holo.storage.service.locator.service.impl.LocatorServiceImpl.updateAllBatch(LocatorServiceImpl.java:422) ~[!/:?]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:352) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-6.1.2.jar!/:6.1.2]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:385) ~[spring-tx-6.1.2.jar!/:6.1.2]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at io.seata.spring.annotation.GlobalTransactionalInterceptor$1.execute(GlobalTransactionalInterceptor.java:188) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.rm.GlobalLockTemplate.execute(GlobalLockTemplate.java:40) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.spring.annotation.GlobalTransactionalInterceptor.handleGlobalLock(GlobalTransactionalInterceptor.java:185) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.spring.annotation.GlobalTransactionalInterceptor.invoke(GlobalTransactionalInterceptor.java:177) ~[seata-all-1.8.0.jar!/:1.8.0]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:717) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at com.holo.storage.service.locator.service.impl.LocatorServiceImpl$$SpringCGLIB$$0.updateAllBatch(<generated>) ~[!/:?]
	at com.holo.storage.service.inventory_move.service.impl.handler.MovePackageDatabaseHandler.movePackageDB(MovePackageDatabaseHandler.java:45) ~[!/:?]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:352) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-6.1.2.jar!/:6.1.2]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:385) ~[spring-tx-6.1.2.jar!/:6.1.2]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:717) ~[spring-aop-6.1.2.jar!/:6.1.2]
	at com.holo.storage.service.inventory_move.service.impl.handler.MovePackageDatabaseHandler$$SpringCGLIB$$0.movePackageDB(<generated>) ~[!/:?]
	at com.holo.storage.service.inventory_move.service.impl.MovePackageServiceImpl.movePackage(MovePackageServiceImpl.java:52) ~[!/:?]
	at com.holo.storage.service.inventory_move.controller.InventoryMoveController.movePackage(InventoryMoveController.java:44) ~[!/:?]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:262) ~[spring-web-6.1.2.jar!/:6.1.2]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:190) ~[spring-web-6.1.2.jar!/:6.1.2]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.2.jar!/:6.1.2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:917) ~[spring-webmvc-6.1.2.jar!/:6.1.2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:829) ~[spring-webmvc-6.1.2.jar!/:6.1.2]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.2.jar!/:6.1.2]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.2.jar!/:6.1.2]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.2.jar!/:6.1.2]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.2.jar!/:6.1.2]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.1.2.jar!/:6.1.2]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:547) ~[jakarta.servlet-api-6.0.0.jar!/:6.0.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.2.jar!/:6.1.2]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) ~[jakarta.servlet-api-6.0.0.jar!/:6.0.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.17.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at com.alibaba.druid.support.jakarta.WebStatFilter.doFilter(WebStatFilter.java:113) ~[druid-1.2.20.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.2.jar!/:6.1.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.2.jar!/:6.1.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.2.jar!/:6.1.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.2.jar!/:6.1.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109) ~[spring-web-6.1.2.jar!/:6.1.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.2.jar!/:6.1.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.2.jar!/:6.1.2]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.2.jar!/:6.1.2]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.17.jar!/:?]
	at java.base/java.lang.VirtualThread.run(VirtualThread.java:309) ~[?:?]
Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:124) ~[mysql-connector-j-8.1.0.jar!/:8.1.0]
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-j-8.1.0.jar!/:8.1.0]
	at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) ~[mysql-connector-j-8.1.0.jar!/:8.1.0]
	at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:972) ~[mysql-connector-j-8.1.0.jar!/:8.1.0]
	at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3225) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_executeQuery(FilterEventAdapter.java:459) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3222) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_executeQuery(FilterEventAdapter.java:459) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeQuery(FilterChainImpl.java:3222) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.executeQuery(PreparedStatementProxyImpl.java:175) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeQuery(DruidPooledPreparedStatement.java:213) ~[druid-1.2.20.jar!/:?]
	at io.seata.rm.datasource.exec.BaseTransactionalExecutor.buildTableRecords(BaseTransactionalExecutor.java:471) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.rm.datasource.exec.SelectForUpdateExecutor.doExecute(SelectForUpdateExecutor.java:94) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.rm.datasource.exec.BaseTransactionalExecutor.execute(BaseTransactionalExecutor.java:124) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:153) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:60) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.rm.datasource.PreparedStatementProxy.execute(PreparedStatementProxy.java:55) ~[seata-all-1.8.0.jar!/:1.8.0]
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:80) ~[mybatis-3.5.15.jar!/:3.5.15]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) ~[mybatis-3.5.15.jar!/:3.5.15]
	at jdk.proxy2/jdk.proxy2.$Proxy214.query(Unknown Source) ~[?:?]
	at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:65) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) ~[mybatis-3.5.15.jar!/:3.5.15]
	at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:81) ~[mybatis-plus-extension-3.5.5.jar!/:3.5.5]
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) ~[mybatis-3.5.15.jar!/:3.5.15]
	at jdk.proxy2/jdk.proxy2.$Proxy213.query(Unknown Source) ~[?:?]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) ~[mybatis-3.5.15.jar!/:3.5.15]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) ~[mybatis-spring-3.0.3.jar!/:3.0.3]
	... 97 more
  1. 死锁INNODB日志:
InnoDB		
=====================================
2024-01-23 14:04:03 139629016434432 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 18 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 308283 srv_active, 0 srv_shutdown, 3940 srv_idle
srv_master_thread log flush and writes: 0
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 94576
OS WAIT ARRAY INFO: signal count 336454
RW-shared spins 0, rounds 0, OS waits 0
RW-excl spins 0, rounds 0, OS waits 0
RW-sx spins 0, rounds 0, OS waits 0
Spin rounds per wait: 0.00 RW-shared, 0.00 RW-excl, 0.00 RW-sx
------------------------
LATEST DETECTED DEADLOCK
------------------------
2024-01-23 13:47:13 139629870262016
*** (1) TRANSACTION:
TRANSACTION 5134245, ACTIVE 0 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 67 lock struct(s), heap size 8312, 4 row lock(s), undo log entries 1
MySQL thread id 1688, OS thread handle 139629280827136, query id 203175281 192.168.12.222 root executing
SELECT id FROM locator WHERE flag_deleted = 0
	AND id IN (9792, 9752) FOR UPDATE

*** (1) HOLDS THE LOCK(S):
RECORD LOCKS space id 48 page no 387 n bits 104 index PRIMARY of table `holo_storage`.`locator` trx id 5134245 lock_mode X locks rec but not gap
Record lock, heap no 32 PHYSICAL RECORD: n_fields 110; compact format; info bits 0
 0: len 8; hex 8000000000002618; asc       & ;;
 1: len 6; hex 0000004e577e; asc    NW~;;
 2: len 7; hex 01000000fd1ccc; asc        ;;
 3: len 10; hex 53532d30312d31303031; asc SS-01-1001;;
 4: len 9; hex e8be93e98081e7babf; asc          ;;
 5: SQL NULL;
 6: SQL NULL;
 7: len 0; hex ; asc ;;
 8: len 2; hex 5353; asc SS;;
 9: len 1; hex 80; asc  ;;
 10: len 4; hex 80000000; asc     ;;
 11: len 4; hex 80000001; asc     ;;
 12: len 1; hex 80; asc  ;;
 13: len 4; hex 80000000; asc     ;;
 14: len 1; hex 80; asc  ;;
 15: len 4; hex 80000000; asc     ;;
 16: len 1; hex 80; asc  ;;
 17: SQL NULL;
 18: SQL NULL;
 19: SQL NULL;
 20: len 5; hex 99b26edbcd; asc   n  ;;
 21: len 1; hex 80; asc  ;;
 22: SQL NULL;
 23: SQL NULL;
 24: SQL NULL;
 25: SQL NULL;
 26: len 4; hex 80000000; asc     ;;
 27: SQL NULL;
 28: SQL NULL;
 29: SQL NULL;
 30: len 4; hex 80000000; asc     ;;
 31: SQL NULL;
 32: SQL NULL;
 33: SQL NULL;
 34: len 4; hex 80000000; asc     ;;
 35: len 4; hex 80000001; asc     ;;
 36: len 1; hex 80; asc  ;;
 37: SQL NULL;
 38: SQL NULL;
 39: SQL NULL;
 40: SQL NULL;
 41: SQL NULL;
 42: SQL NULL;
 43: len 10; hex 80000000000000000000; asc           ;;
 44: len 10; hex 80000000000000000000; asc           ;;
 45: len 8; hex 800000000000000c; asc         ;;
 46: len 5; hex 53532d3031; asc SS-01;;
 47: len 12; hex e8be93e98081e7babf2d3031; asc          -01;;
 48: len 8; hex 8000000000000001; asc         ;;
 49: len 7; hex 4c4b4b462d3031; asc LKKF-01;;
 50: len 12; hex e7ab8be5ba93e5ba93e688bf; asc             ;;
 51: len 8; hex 8000000000000001; asc         ;;
 52: len 5; hex 47584a434b; asc GXJCK;;
 53: len 15; hex e7a185e6a9a1e883b6e4bb93e5ba93; asc                ;;
 54: len 8; hex 8000000000000001; asc         ;;
 55: len 6; hex 5852574c5a58; asc XRWLZX;;
 56: len 18; hex e585b4e7919ee789a9e6b581e4b8ade5bf83; asc                   ;;
 57: SQL NULL;
 58: SQL NULL;
 59: SQL NULL;
 60: SQL NULL;
 61: SQL NULL;
 62: SQL NULL;
 63: SQL NULL;
 64: SQL NULL;
 65: SQL NULL;
 66: SQL NULL;
 67: SQL NULL;
 68: SQL NULL;
 69: SQL NULL;
 70: SQL NULL;
 71: SQL NULL;
 72: SQL NULL;
 73: SQL NULL;
 74: SQL NULL;
 75: SQL NULL;
 76: SQL NULL;
 77: SQL NULL;
 78: len 0; hex ; asc ;;
 79: SQL NULL;
 80: len 0; hex ; asc ;;
 81: SQL NULL;
 82: SQL NULL;
 83: SQL NULL;
 84: SQL NULL;
 85: SQL NULL;
 86: SQL NULL;
 87: SQL NULL;
 88: SQL NULL;
 89: SQL NULL;
 90: SQL NULL;
 91: SQL NULL;
 92: SQL NULL;
 93: SQL NULL;
 94: SQL NULL;
 95: SQL NULL;
 96: SQL NULL;
 97: SQL NULL;
 98: SQL NULL;
 99: SQL NULL;
 100: SQL NULL;
 101: len 1; hex 81; asc  ;;
 102: len 1; hex 80; asc  ;;
 103: len 4; hex 800001a3; asc     ;;
 104: len 10; hex 737570657261646d696e; asc superadmin;;
 105: len 15; hex e8b685e7baa7e7aea1e79086e59198; asc                ;;
 106: len 5; hex 99b1eaa604; asc      ;;
 107: SQL NULL;
 108: SQL NULL;
 109: len 5; hex 99b26edbcd; asc   n  ;;


*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 48 page no 27 n bits 584 index code of table `holo_storage`.`locator` trx id 5134245 lock_mode X locks rec but not gap waiting
Record lock, heap no 31 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 15; hex 53524d2d30312d30322d30342d3038; asc SRM-01-02-04-08;;
 1: len 1; hex 80; asc  ;;
 2: len 8; hex 8000000000000074; asc        t;;


*** (2) TRANSACTION:
TRANSACTION 5134244, ACTIVE 0 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 334 lock struct(s), heap size 41080, 6 row lock(s), undo log entries 1
MySQL thread id 1691, OS thread handle 139629261928192, query id 203175245 192.168.12.222 root executing
SELECT id FROM locator WHERE flag_deleted = 0
	AND id IN (116, 9753) FOR UPDATE

*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 48 page no 27 n bits 584 index code of table `holo_storage`.`locator` trx id 5134244 lock_mode X locks rec but not gap
Record lock, heap no 31 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 15; hex 53524d2d30312d30322d30342d3038; asc SRM-01-02-04-08;;
 1: len 1; hex 80; asc  ;;
 2: len 8; hex 8000000000000074; asc        t;;


*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 48 page no 387 n bits 104 index PRIMARY of table `holo_storage`.`locator` trx id 5134244 lock_mode X locks rec but not gap waiting
Record lock, heap no 32 PHYSICAL RECORD: n_fields 110; compact format; info bits 0
 0: len 8; hex 8000000000002618; asc       & ;;
 1: len 6; hex 0000004e577e; asc    NW~;;
 2: len 7; hex 01000000fd1ccc; asc        ;;
 3: len 10; hex 53532d30312d31303031; asc SS-01-1001;;
 4: len 9; hex e8be93e98081e7babf; asc          ;;
 5: SQL NULL;
 6: SQL NULL;
 7: len 0; hex ; asc ;;
 8: len 2; hex 5353; asc SS;;
 9: len 1; hex 80; asc  ;;
 10: len 4; hex 80000000; asc     ;;
 11: len 4; hex 80000001; asc     ;;
 12: len 1; hex 80; asc  ;;
 13: len 4; hex 80000000; asc     ;;
 14: len 1; hex 80; asc  ;;
 15: len 4; hex 80000000; asc     ;;
 16: len 1; hex 80; asc  ;;
 17: SQL NULL;
 18: SQL NULL;
 19: SQL NULL;
 20: len 5; hex 99b26edbcd; asc   n  ;;
 21: len 1; hex 80; asc  ;;
 22: SQL NULL;
 23: SQL NULL;
 24: SQL NULL;
 25: SQL NULL;
 26: len 4; hex 80000000; asc     ;;
 27: SQL NULL;
 28: SQL NULL;
 29: SQL NULL;
 30: len 4; hex 80000000; asc     ;;
 31: SQL NULL;
 32: SQL NULL;
 33: SQL NULL;
 34: len 4; hex 80000000; asc     ;;
 35: len 4; hex 80000001; asc     ;;
 36: len 1; hex 80; asc  ;;
 37: SQL NULL;
 38: SQL NULL;
 39: SQL NULL;
 40: SQL NULL;
 41: SQL NULL;
 42: SQL NULL;
 43: len 10; hex 80000000000000000000; asc           ;;
 44: len 10; hex 80000000000000000000; asc           ;;
 45: len 8; hex 800000000000000c; asc         ;;
 46: len 5; hex 53532d3031; asc SS-01;;
 47: len 12; hex e8be93e98081e7babf2d3031; asc          -01;;
 48: len 8; hex 8000000000000001; asc         ;;
 49: len 7; hex 4c4b4b462d3031; asc LKKF-01;;
 50: len 12; hex e7ab8be5ba93e5ba93e688bf; asc             ;;
 51: len 8; hex 8000000000000001; asc         ;;
 52: len 5; hex 47584a434b; asc GXJCK;;
 53: len 15; hex e7a185e6a9a1e883b6e4bb93e5ba93; asc                ;;
 54: len 8; hex 8000000000000001; asc         ;;
 55: len 6; hex 5852574c5a58; asc XRWLZX;;
 56: len 18; hex e585b4e7919ee789a9e6b581e4b8ade5bf83; asc                   ;;
 57: SQL NULL;
 58: SQL NULL;
 59: SQL NULL;
 60: SQL NULL;
 61: SQL NULL;
 62: SQL NULL;
 63: SQL NULL;
 64: SQL NULL;
 65: SQL NULL;
 66: SQL NULL;
 67: SQL NULL;
 68: SQL NULL;
 69: SQL NULL;
 70: SQL NULL;
 71: SQL NULL;
 72: SQL NULL;
 73: SQL NULL;
 74: SQL NULL;
 75: SQL NULL;
 76: SQL NULL;
 77: SQL NULL;
 78: len 0; hex ; asc ;;
 79: SQL NULL;
 80: len 0; hex ; asc ;;
 81: SQL NULL;
 82: SQL NULL;
 83: SQL NULL;
 84: SQL NULL;
 85: SQL NULL;
 86: SQL NULL;
 87: SQL NULL;
 88: SQL NULL;
 89: SQL NULL;
 90: SQL NULL;
 91: SQL NULL;
 92: SQL NULL;
 93: SQL NULL;
 94: SQL NULL;
 95: SQL NULL;
 96: SQL NULL;
 97: SQL NULL;
 98: SQL NULL;
 99: SQL NULL;
 100: SQL NULL;
 101: len 1; hex 81; asc  ;;
 102: len 1; hex 80; asc  ;;
 103: len 4; hex 800001a3; asc     ;;
 104: len 10; hex 737570657261646d696e; asc superadmin;;
 105: len 15; hex e8b685e7baa7e7aea1e79086e59198; asc                ;;
 106: len 5; hex 99b1eaa604; asc      ;;
 107: SQL NULL;
 108: SQL NULL;
 109: len 5; hex 99b26edbcd; asc   n  ;;

*** WE ROLL BACK TRANSACTION (1)
------------
TRANSACTIONS
------------
Trx id counter 5157575
Purge done for trx's n:o < 5157569 undo n:o < 0 state: running but idle
History list length 5
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421105314177440, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314175824, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314176632, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314173400, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314166936, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314161280, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314163704, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314154008, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314153200, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314154816, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314174208, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314165320, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314156432, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314171784, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314170976, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314162088, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314170168, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314169360, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314168552, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314167744, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314166128, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314164512, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314162896, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314160472, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314158856, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314158048, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314157240, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314155624, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314151584, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314150776, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314148352, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314146736, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 421105314145928, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
---TRANSACTION 5157574, ACTIVE (PREPARED) 0 sec
2 lock struct(s), heap size 1128, 1 row lock(s), undo log entries 1
MySQL thread id 1724, OS thread handle 139629048076032, query id 203836473 172.17.0.1 root waiting for handler commit
commit
---TRANSACTION 5157572, ACTIVE (PREPARED) 0 sec
2 lock struct(s), heap size 1128, 1 row lock(s), undo log entries 1
MySQL thread id 1733, OS thread handle 139629262984960, query id 203836431 172.17.0.1 root waiting for handler commit
commit
---TRANSACTION 5157571, ACTIVE (PREPARED) 0 sec
2 lock struct(s), heap size 1128, 1 row lock(s), undo log entries 1
MySQL thread id 1740, OS thread handle 139629045962496, query id 203836430 172.17.0.1 root waiting for handler commit
commit
---TRANSACTION 5157570, ACTIVE (PREPARED) 0 sec
2 lock struct(s), heap size 1128, 1 row lock(s), undo log entries 1
MySQL thread id 1748, OS thread handle 139629258757888, query id 203836428 172.17.0.1 root waiting for handler commit
commit
--------
FILE I/O
--------
I/O thread 0 state: waiting for completed aio requests ((null))
I/O thread 1 state: waiting for completed aio requests (insert buffer thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
Pending normal aio reads: [0, 0, 0, 0] , aio writes: [0, 0, 0, 0] ,
 ibuf aio reads:
Pending flushes (fsync) log: 1; buffer pool: 0
28712 OS file reads, 5942851 OS file writes, 3054261 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 43.11 writes/s, 18.10 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 8 merges
merged operations:
 insert 8, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 34679, node heap has 2 buffer(s)
Hash table size 34679, node heap has 24 buffer(s)
Hash table size 34679, node heap has 6 buffer(s)
Hash table size 34679, node heap has 1 buffer(s)
Hash table size 34679, node heap has 3 buffer(s)
Hash table size 34679, node heap has 2 buffer(s)
Hash table size 34679, node heap has 4 buffer(s)
Hash table size 34679, node heap has 12 buffer(s)
3162.71 hash searches/s, 292.76 non-hash searches/s
---
LOG
---
Log sequence number          1971621584
Log buffer assigned up to    1971621584
Log buffer completed up to   1971621584
Log written up to            1971621584
Log flushed up to            1971621064
Added dirty pages up to      1971621584
Pages flushed up to          1965202826
Last checkpoint at           1965202826
Log minimum file id is       572
Log maximum file id is       602
5101058 log i/o's done, 39.11 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 0
Dictionary memory allocated 1764847
Buffer pool size   8192
Free buffers       1027
Database pages     7111
Old database pages 2604
Modified db pages  781
Pending reads      0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 159591, not young 736674
0.93 youngs/s, 0.00 non-youngs/s
Pages read 28654, created 17227, written 613067
0.00 reads/s, 0.00 creates/s, 3.02 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 7111, unzip_LRU len: 0
I/O sum[160]:cur[0], unzip sum[0]:cur[0]
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
3 read views open inside InnoDB
Process ID=1, Main thread ID=139629772658432 , state=sleeping
Number of rows inserted 360218, updated 2526005, deleted 37949, read 371805889565
4.00 inserts/s, 10.78 updates/s, 3.50 deletes/s, 1164131.05 reads/s
Number of system rows inserted 5549, updated 5765, deleted 336, read 746853
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 2.56 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================
  1. 在本地事务外捕获死锁异常的话,会报错
io.seata.rm.datasource.exec.SelectForUpdateExecutor: mysql release save point error.
java.sql.SQLSyntaxErrorException: SAVEPOINT 9114eff0_9a3f_4fdf_81cb_3fa15ed63351 does not exist
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:121) ~[mysql-connector-j-8.3.0.jar!/:8.3.0]
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-j-8.3.0.jar!/:8.3.0]
	at com.mysql.cj.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1344) ~[mysql-connector-j-8.3.0.jar!/:8.3.0]
	at com.mysql.cj.jdbc.StatementImpl.executeLargeUpdate(StatementImpl.java:2090) ~[mysql-connector-j-8.3.0.jar!/:8.3.0]
	at com.mysql.cj.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1253) ~[mysql-connector-j-8.3.0.jar!/:8.3.0]
	at com.mysql.cj.jdbc.ConnectionImpl.releaseSavepoint(ConnectionImpl.java:1754) ~[mysql-connector-j-8.3.0.jar!/:8.3.0]
	at com.alibaba.druid.filter.FilterChainImpl.connection_releaseSavepoint(FilterChainImpl.java:663) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.filter.FilterAdapter.connection_releaseSavepoint(FilterAdapter.java:947) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.filter.FilterChainImpl.connection_releaseSavepoint(FilterChainImpl.java:658) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.filter.FilterAdapter.connection_releaseSavepoint(FilterAdapter.java:947) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.filter.FilterChainImpl.connection_releaseSavepoint(FilterChainImpl.java:658) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.releaseSavepoint(ConnectionProxyImpl.java:379) ~[druid-1.2.20.jar!/:?]
	at com.alibaba.druid.pool.DruidPooledConnection.releaseSavepoint(DruidPooledConnection.java:861) ~[druid-1.2.20.jar!/:?]
	at io.seata.rm.datasource.exec.SelectForUpdateExecutor.doExecute(SelectForUpdateExecutor.java:122) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.rm.datasource.exec.BaseTransactionalExecutor.execute(BaseTransactionalExecutor.java:124) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:153) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:60) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.rm.datasource.PreparedStatementProxy.execute(PreparedStatementProxy.java:55) ~[seata-all-1.8.0.jar!/:1.8.0]
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:80) ~[mybatis-3.5.15.jar!/:3.5.15]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) ~[mybatis-3.5.15.jar!/:3.5.15]
	at jdk.proxy2/jdk.proxy2.$Proxy214.query(Unknown Source) ~[?:?]
	at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:65) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) ~[mybatis-3.5.15.jar!/:3.5.15]
	at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:81) ~[mybatis-plus-extension-3.5.5.jar!/:3.5.5]
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) ~[mybatis-3.5.15.jar!/:3.5.15]
	at jdk.proxy2/jdk.proxy2.$Proxy213.query(Unknown Source) ~[?:?]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) ~[mybatis-3.5.15.jar!/:3.5.15]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) ~[mybatis-3.5.15.jar!/:3.5.15]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) ~[mybatis-spring-3.0.3.jar!/:3.0.3]
	at jdk.proxy2/jdk.proxy2.$Proxy153.selectList(Unknown Source) ~[?:?]
	at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) ~[mybatis-spring-3.0.3.jar!/:3.0.3]
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:164) ~[mybatis-plus-core-3.5.5.jar!/:3.5.5]
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:77) ~[mybatis-plus-core-3.5.5.jar!/:3.5.5]
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:152) ~[mybatis-plus-core-3.5.5.jar!/:3.5.5]
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89) ~[mybatis-plus-core-3.5.5.jar!/:3.5.5]
	at jdk.proxy2/jdk.proxy2.$Proxy171.selectList(Unknown Source) ~[?:?]
	at com.holo.common.core.service.HoloBaseServiceImpl.listByIdsForUpdate(HoloBaseServiceImpl.java:127) ~[holo-common-core-1.0.jar!/:?]
	at com.holo.storage.service.locator.service.impl.LocatorServiceImpl.updateBatch(LocatorServiceImpl.java:353) ~[!/:?]
	at com.holo.storage.service.locator.service.impl.LocatorServiceImpl.updateAllBatch(LocatorServiceImpl.java:422) ~[!/:?]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:351) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-6.1.3.jar!/:6.1.3]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:385) ~[spring-tx-6.1.3.jar!/:6.1.3]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at io.seata.spring.annotation.GlobalTransactionalInterceptor$1.execute(GlobalTransactionalInterceptor.java:188) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.rm.GlobalLockTemplate.execute(GlobalLockTemplate.java:40) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.spring.annotation.GlobalTransactionalInterceptor.handleGlobalLock(GlobalTransactionalInterceptor.java:185) ~[seata-all-1.8.0.jar!/:1.8.0]
	at io.seata.spring.annotation.GlobalTransactionalInterceptor.invoke(GlobalTransactionalInterceptor.java:177) ~[seata-all-1.8.0.jar!/:1.8.0]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:717) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at com.holo.storage.service.locator.service.impl.LocatorServiceImpl$$SpringCGLIB$$0.updateAllBatch(<generated>) ~[!/:?]
	at com.holo.storage.service.inventory_move.service.impl.handler.MovePackageDatabaseHandler.movePackageDB(MovePackageDatabaseHandler.java:45) ~[!/:?]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:351) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-6.1.3.jar!/:6.1.3]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:385) ~[spring-tx-6.1.3.jar!/:6.1.3]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:717) ~[spring-aop-6.1.3.jar!/:6.1.3]
	at com.holo.storage.service.inventory_move.service.impl.handler.MovePackageDatabaseHandler$$SpringCGLIB$$0.movePackageDB(<generated>) ~[!/:?]
	at com.holo.storage.service.inventory_move.service.impl.MovePackageServiceImpl.movePackage(MovePackageServiceImpl.java:53) ~[!/:?]
	at com.holo.storage.service.inventory_move.controller.InventoryMoveController.movePackage(InventoryMoveController.java:44) ~[!/:?]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:261) ~[spring-web-6.1.3.jar!/:6.1.3]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:189) ~[spring-web-6.1.3.jar!/:6.1.3]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.3.jar!/:6.1.3]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:917) ~[spring-webmvc-6.1.3.jar!/:6.1.3]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:829) ~[spring-webmvc-6.1.3.jar!/:6.1.3]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.3.jar!/:6.1.3]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.3.jar!/:6.1.3]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.3.jar!/:6.1.3]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.3.jar!/:6.1.3]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.1.3.jar!/:6.1.3]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:547) ~[jakarta.servlet-api-6.0.0.jar!/:6.0.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.3.jar!/:6.1.3]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) ~[jakarta.servlet-api-6.0.0.jar!/:6.0.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.18.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at com.alibaba.druid.support.jakarta.WebStatFilter.doFilter(WebStatFilter.java:113) ~[druid-1.2.20.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.3.jar!/:6.1.3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.3.jar!/:6.1.3]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.3.jar!/:6.1.3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.3.jar!/:6.1.3]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109) ~[spring-web-6.1.3.jar!/:6.1.3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.3.jar!/:6.1.3]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.3.jar!/:6.1.3]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.3.jar!/:6.1.3]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.18.jar!/:?]
	at java.base/java.lang.VirtualThread.run(VirtualThread.java:309) ~[?:?]

Ⅲ. Describe what you expected to happen

我认为ID不同时不应当发生死锁,但不知道是seata的原因还是MySQL的原因。另一方面,我不太理解为什么我在本地事务外捕获异常后seata会报错。

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

Ⅴ. Anything else we need to know?

Ⅵ. Environment:

  • JDK version(e.g. java -version): 21.0.2
  • Seata client/server version: 1.8.0
  • Database version: 8.0.36

Self-revolution avatar Jan 23 '24 08:01 Self-revolution

没有代码例子如何判断什么叫本地事务外捕获异常? How can I tell what it means to catch an exception outside of a local transaction without a code example?

funky-eyes avatar Jan 23 '24 08:01 funky-eyes

@Service
@RequiredArgsConstructor
public class MovePackageServiceImpl implements MovePackageService {

    private final MovePackageDatabaseHandler movePackageDatabaseHandler;

    @Override
    public void movePackage(MovePackageReqBO movePackageReqBO) {
        String reqJson = JsonUtils.toString(movePackageReqBO);
        for (int i = 1; ; i++) {
        // ......
        try {
            movePackageDatabaseHandler.movePackageDB(movePackageReqBO.getDbBuffer());
            return;
        } catch (DeadlockLoserDataAccessException e) {
            if (i == tryTimes) throw e;
            movePackageReqBO = JsonUtils.parseObject(reqJson, MovePackageReqBO.class);
        }
    }
}
@Service
@RequiredArgsConstructor
public class MovePackageDatabaseHandler {

    private final LocatorService locatorService;

    @Transactional(rollbackFor = Exception.class)
    public void movePackageDB(DbBuffer dbBuffer) {
        // 这里是本地事务的最外层,其他服务调用movePackage时开启了全局事务
        locatorService.updateAllBatch(new LocatorUpdateBatchReqBO(new ArrayList<>(dbBuffer.getLocatorUpdateReqBOMap().values())));
    }

}
@Service
@RequiredArgsConstructor
public class LocatorServiceImpl extends HoloBaseServiceImpl<LocatorDao, LocatorDO> implements LocatorService {

    @Override
    @GlobalLock
    @Transactional(rollbackFor = Exception.class)
    public List<LocatorRespBO> updateAllBatch(LocatorUpdateBatchReqBO locatorUpdateBatchReqBO) {
        // ......
        // 手动根据ID添加行锁
        List<DO> resList = baseMapper.selectList(Wrappers.lambdaQuery(getEntityClass()).in(BaseDOCommon::getId, idList).last("FOR UPDATE"));
        // ......
        // 调用MybatisPlus的Update方法更新添加了行锁的数据
        // ......
    }

}

Self-revolution avatar Jan 23 '24 08:01 Self-revolution

你确定你的代码加了trycatch才会抛异常?如果是重试的时候说事务已经回滚,请确认是否存在切面式的事务在movePackage时就已经进入了一个本地事务,所以导致了该问题,你可以将updateAllBatch上的@Transactional(rollbackFor = Exception.class)改为@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)

Are you sure your code added trycatch to throw the exception? If it's the retry that says the transaction has been rolled back, make sure there is no cut-and-dried transaction that has gone into a local transaction at the time of movePackage that's causing the issue, you can change the @Transactional(rollbackFor = Exception.class) on updateAllBatch to @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)

funky-eyes avatar Jan 24 '24 01:01 funky-eyes

我确定,没加try-catch之前的报死锁异常,捕获异常后,seata报错mysql release save point error.,且这个报错是在下一次循环的重试之前,因为我在每次循环后打印了日志

for (int i = 1; ; i++) {
    //......
    try {
        movePackageDatabaseHandler.movePackageDB(movePackageReqBO.getDbBuffer());
        return;
    } catch (DataVersionException | DeadlockLoserDataAccessException e) {
        if (i == tryTimes) throw e;
        log.warn("出现异常,进行第{}次重试", i);
        movePackageReqBO = JsonUtils.parseObject(reqJson, MovePackageReqBO.class);
    }
}

这个异常日志在我的日志之前

ERROR 2024-01-23 13:46:42.010 [tomcat-handler-691553] i.s.r.datasource.exec.SelectForUpdateExecutor: mysql release save point error.
java.sql.SQLSyntaxErrorException: SAVEPOINT 4f908cbd_b782_4dab_8d8b_e29c47860831 does not exist
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:121) ~[mysql-connector-j-8.3.0.jar!/:8.3.0]
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-j-8.3.0.jar!/:8.3.0]
	at ......
WARN  2024-01-23 13:46:42.011 [tomcat-handler-691553] c.h.s.service.inventory_move.service.impl.MovePackageServiceImpl: 出现异常,进行第1次重试

我的MovePackageServiceImpl上层就是Controller了,通过openfeign调用的Controller接口,并没有其他上层本地事务。

此外,关于死锁的原因,我排查出我的数据库对于seata自动生成的SELECT id FROM locator WHERE flag_deleted = 0 AND id IN (9792, 9752) FOR UPDATE这条SQL,其执行计划不知为何没有命中PRIMARY KEY (id),而是命中索引UNIQUE KEY code (code, flag_deleted),是不是因此在加锁时发生了冲突

Self-revolution avatar Jan 24 '24 03:01 Self-revolution

补充一下查询SQL执行计划的结果 QQ截图20240124112222

Self-revolution avatar Jan 24 '24 03:01 Self-revolution

当查询的字段变多的时候,又可以命中主键,比如增加一个name字段后: QQ截图20240124113452

Self-revolution avatar Jan 24 '24 03:01 Self-revolution

我确定,没加try-catch之前的报死锁异常,捕获异常后,seata报错mysql release save point error.,且这个报错是在下一次循环的重试之前,因为我在每次循环后打印了日志

for (int i = 1; ; i++) {
    //......
    try {
        movePackageDatabaseHandler.movePackageDB(movePackageReqBO.getDbBuffer());
        return;
    } catch (DataVersionException | DeadlockLoserDataAccessException e) {
        if (i == tryTimes) throw e;
        log.warn("出现异常,进行第{}次重试", i);
        movePackageReqBO = JsonUtils.parseObject(reqJson, MovePackageReqBO.class);
    }
}

这个异常日志在我的日志之前

ERROR 2024-01-23 13:46:42.010 [tomcat-handler-691553] i.s.r.datasource.exec.SelectForUpdateExecutor: mysql release save point error.
java.sql.SQLSyntaxErrorException: SAVEPOINT 4f908cbd_b782_4dab_8d8b_e29c47860831 does not exist
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:121) ~[mysql-connector-j-8.3.0.jar!/:8.3.0]
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-j-8.3.0.jar!/:8.3.0]
	at ......
WARN  2024-01-23 13:46:42.011 [tomcat-handler-691553] c.h.s.service.inventory_move.service.impl.MovePackageServiceImpl: 出现异常,进行第1次重试

我的MovePackageServiceImpl上层就是Controller了,通过openfeign调用的Controller接口,并没有其他上层本地事务。

此外,关于死锁的原因,我排查出我的数据库对于seata自动生成的SELECT id FROM locator WHERE flag_deleted = 0 AND id IN (9792, 9752) FOR UPDATE这条SQL,其执行计划不知为何没有命中PRIMARY KEY (id),而是命中索引UNIQUE KEY code (code, flag_deleted),是不是因此在加锁时发生了冲突

mysql release save point error To troubleshoot this issue, check if there is a local transaction on the trycatch method.

funky-eyes avatar Jan 25 '24 01:01 funky-eyes

当查询的字段变多的时候,又可以命中主键,比如增加一个name字段后: QQ截图20240124113452

这个死锁触发应该跟mysql的版本和优化器策略有关,但看这两个for update语句,理论上只要命中索引肯定不会产生死锁,所以这个问题不属于seata,我更关心的是mysql release save point error 这个问题

This deadlock trigger should be related to mysql version and optimizer strategy, but look at these two for update statement, theoretically as long as the hit index certainly will not generate deadlock, so this problem does not belong to seata, I am more concerned about mysql release save point error this problem

funky-eyes avatar Jan 25 '24 01:01 funky-eyes

我通过执行MySQL的分析表命令修复了索引错误,解决了死锁问题。 对于mysql release save point error异常这个问题,通过日志可以看出,调用链是很清晰的,我确定没有上层的本地事务。我之前也没有遇到过这个报错信息,我怀疑会不会和org.springframework.dao.DeadlockLoserDataAccessException这个异常的出现有关。有没有可能是seata检查全局锁时,执行SELECT id FROM locator WHERE flag_deleted = 0 AND id IN (9792, 9752) FOR UPDATE时出现的死锁,导致了io.seata.rm.datasource.exec.SelectForUpdateExecutor出现mysql release save point error异常

Self-revolution avatar Jan 25 '24 02:01 Self-revolution

我通过执行MySQL的分析表命令修复了索引错误,解决了死锁问题。 对于mysql release save point error异常这个问题,通过日志可以看出,调用链是很清晰的,我确定没有上层的本地事务。我之前也没有遇到过这个报错信息,我怀疑会不会和org.springframework.dao.DeadlockLoserDataAccessException这个异常的出现有关。有没有可能是seata检查全局锁时,执行SELECT id FROM locator WHERE flag_deleted = 0 AND id IN (9792, 9752) FOR UPDATE时出现的死锁,导致了io.seata.rm.datasource.exec.SelectForUpdateExecutor出现mysql release save point error异常

server的全局锁跟你本地的死锁的关系是什么?

funky-eyes avatar Jul 16 '24 01:07 funky-eyes

这个问题已经解决了,是MySQL的执行计划有问题,通过分析表命令进行了修复,由于死锁的SQL语句是seata生成的,所以之前没有判断出是数据库的问题还是MySQL的问题

Self-revolution avatar Aug 05 '24 04:08 Self-revolution

这个问题已经解决了,是MySQL的执行计划有问题,通过分析表命令进行了修复,由于死锁的SQL语句是seata生成的,所以之前没有判断出是数据库的问题还是MySQL的问题

可以分享下到底是如何分析和修复的吗?以免更多人遇到相关问题 Can you share how to analyze and fix it? So as not to encounter related problems for more people

funky-eyes avatar Aug 21 '24 08:08 funky-eyes