You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@seata.apache.org by "Xiamu-ssr (via GitHub)" <gi...@apache.org> on 2024/01/03 12:45:36 UTC
[I] 2.0.0 TCC模式@BusinessActionContextParameter修饰的参数失效,无法在BusinessActionContext获取 [incubator-seata]
Xiamu-ssr opened a new issue, #6235:
URL: https://github.com/apache/incubator-seata/issues/6235
<!-- Please do not use this issue template to report security vulnerabilities but refer to our [security policy](https://github.com/seata/seata/security/policy). -->
- [x] I have searched the [issues](https://github.com/seata/seata/issues) of this repository and believe that this is not a duplicate.
### Ⅰ. Issue Description
我在Windows IDEA本地学习简单的微服务,Nacos v2.3.0、Seata-server 2.0.0、 MySQL5.7都在docker desktop for windows下,他们都运行良好。

在微服务中,当我使用io-seata 2.0.0的包时,Seata的TCC模式BusinessActionContext无法获取@BusinessActionContextParameter修饰的参数。下一小节,我会给更出详细的情况。
```
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<!--版本较低,1.3.0,因此排除-->
<exclusion>
<artifactId>seata-spring-boot-starter</artifactId>
<groupId>io.seata</groupId>
</exclusion>
</exclusions>
</dependency>
<!--seata starter 采用2.0.0版本-->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
```
### Ⅱ. Describe what happened
这是一个简单的项目,包含order、account、storage三个微服务,order创建订单,然后调用account扣除余额,紧接着调用storage扣除库存,就和你们Seata官方提供的样例基本是一样的。我只在account微服务使用TCC模式,其余默认AT。我的account微服务的yaml配置也是健康的。问题主要是出在account微服务,接下来介绍account相关代码。
这是**controller**
```java
@RestController
@RequestMapping("account")
public class AccountController {
@Autowired
private AccountTCCService accountService;
@PutMapping("/{userId}/{money}")
public ResponseEntity<Void> deduct(@PathVariable("userId") String userId, @PathVariable("money") Integer money){
accountService.deduct(null, userId, money);
return ResponseEntity.noContent().build();
}
}
```
这是**AccountTCCService**
```java
@LocalTCC
public interface AccountTCCService {
@TwoPhaseBusinessAction(name = "deduct", commitMethod = "deductConfirm", rollbackMethod = "deductCancel")
boolean deduct(
BusinessActionContext ctx,
@BusinessActionContextParameter(paramName = "userId") String userId,
@BusinessActionContextParameter(paramName = "money") int money
);
boolean deductConfirm(BusinessActionContext ctx);
boolean deductCancel(BusinessActionContext ctx);
}
```
这是**AccountTCCService**实现,我在两处进行了断点Debug。具体位置在代码注释表明。只需要关注try和cancel阶段的开头BusinessActionContext 的打印输出。
```java
@Service
@Slf4j
public class AccountTCCServiceImpl implements AccountTCCService {
@Autowired
private AccountMapper accountMapper;
@Autowired
private AccountFreezeMapper accountFreezeMapper;
@Override
@Transactional
public boolean deduct(BusinessActionContext ctx, String userId, int money) {
System.out.println(ctx);//第一处断点
if (ctx != null){
Object userId2 = ctx.getActionContext("userId");
Object money2 = ctx.getActionContext("money");
System.out.println(userId2);
System.out.println(money2);
}
throw new RuntimeException("扣款失败,可能是余额不足!");
}
@Override
public boolean deductConfirm(BusinessActionContext ctx) {
return true;
}
@Override
public boolean deductCancel(BusinessActionContext ctx) {
Object userId = ctx.getActionContext("userId");//第二处断点
Object money = ctx.getActionContext("money");
System.out.println(userId);
System.out.println(money);
return false;
}
}
```
发送一个请求,故意让account在try阶段失败后进入cancel阶段。
当处于第一处断点时,可以看到ctx中的actionContext中并没有userId和money字段。

步过这个断点,将后面的输出执行,控制台看到两个null

接着恢复程序,暂停于第二处断点,ctx中的actionContext中也没有userId和money字段。

步过这个断点,将后面的输出执行,控制台也是看到两个null

由此判断Seata并没有正常将由@BusinessActionContextParameter修饰的参数载入BusinessActionContext。
经过各种办法,都无法从BusinessActionContext获取参数,最后尝试将io-seata降到1.4.2版本,其余没有改动。
```
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<!--版本较低,1.3.0,因此排除-->
<exclusion>
<artifactId>seata-spring-boot-starter</artifactId>
<groupId>io.seata</groupId>
</exclusion>
</exclusions>
</dependency>
<!--seata starter 采用1.4.2版本-->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>
```
再来一次断点Debug,发现可以正常获取参数,依旧是四张图片,对应上面的四张。




提出以下疑问:
1. io-seata 2.0.0是否真的存在@BusinessActionContextParameter的bug
2. io-seata 2.0.0应该搭配Seata-server 2.0.0使用吧?io-seata 1.4.2 搭配Seata-Server 2.0.0并不是完美的解决方案?
我并不是一个资深的开发者,上面的描述如果有任何不恰当之处,欢迎指正。
### Ⅵ. Environment:
- JDK version(e.g. `java -version`): 1.8
- Seata client/server version: 2.0.0
- Database version: MySQL5.7
- OS(e.g. `uname -a`): Windows
- Others:
- Docker Desktop for Windows 4.23.0
--
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: dev-unsubscribe@seata.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@seata.apache.org
For additional commands, e-mail: dev-help@seata.apache.org
Re: [I] 2.0.0 TCC模式@BusinessActionContextParameter修饰的参数失效,无法在BusinessActionContext获取 [incubator-seata]
Posted by "funky-eyes (via GitHub)" <gi...@apache.org>.
funky-eyes commented on issue #6235:
URL: https://github.com/apache/incubator-seata/issues/6235#issuecomment-1876397212
高版本中BusinessActionContextParameter和TwoPhaseBusinessAction推荐都放在实现类中,接口上的做法后续将会废除,由于TwoPhaseBusinessAction注解被加到了实现类和接口上,导致因为父类和子类的TwoPhaseBusinessAction注解对应的方法是相同的一个,其对应的重写方法被没有BusinessActionContextParameter注解的方法覆盖,导致了BusinessActionContextParameter失效的问题
In the high version BusinessActionContextParameter and TwoPhaseBusinessAction recommendations are placed in the implementation class, the practice on the interface will be abolished later, because TwoPhaseBusinessAction annotations are added to the implementation class and interface, resulting in the same method as the TwoPhaseBusinessAction annotations of the parent class and the child class, the corresponding override method is not BusinessActionContextParameter annotation method coverage, resulting in BusinessActionContextParameter failure
--
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: dev-unsubscribe@seata.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@seata.apache.org
For additional commands, e-mail: dev-help@seata.apache.org
Re: [I] 2.0.0 TCC模式@BusinessActionContextParameter修饰的参数失效,无法在BusinessActionContext获取 [incubator-seata]
Posted by "Xiamu-ssr (via GitHub)" <gi...@apache.org>.
Xiamu-ssr commented on issue #6235:
URL: https://github.com/apache/incubator-seata/issues/6235#issuecomment-1876610361
谢谢。当我把注解全部从接口转移到实现类后,问题解决了。
这是接口类
```java
public interface AccountTCCService {
boolean deduct(
BusinessActionContext ctx,
String userId,
int money
);
boolean deductConfirm(BusinessActionContext ctx);
boolean deductCancel(BusinessActionContext ctx);
}
```
这是实现类
```java
@Service
@Slf4j
@LocalTCC
public class AccountTCCServiceImpl implements AccountTCCService {
@Autowired
private AccountMapper accountMapper;
@Autowired
private AccountFreezeMapper accountFreezeMapper;
@Override
@Transactional
@TwoPhaseBusinessAction(name = "deduct", commitMethod = "deductConfirm", rollbackMethod = "deductCancel")
public boolean deduct(
BusinessActionContext ctx,
@BusinessActionContextParameter(paramName = "userId") String userId,
@BusinessActionContextParameter(paramName = "money") int money
) {
System.out.println(ctx);//第一处断点
if (ctx != null){
Object userId2 = ctx.getActionContext("userId");
Object money2 = ctx.getActionContext("money");
System.out.println(userId2);
System.out.println(money2);
}
throw new RuntimeException("扣款失败,可能是余额不足!");
}
@Override
public boolean deductConfirm(BusinessActionContext ctx) {
return true;
}
@Override
public boolean deductCancel(BusinessActionContext ctx) {
Object userId = ctx.getActionContext("userId");//第二处断点
Object money = ctx.getActionContext("money");
System.out.println(userId);
System.out.println(money);
return false;
}
}
```

--
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: dev-unsubscribe@seata.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@seata.apache.org
For additional commands, e-mail: dev-help@seata.apache.org
Re: [I] 2.0.0 TCC模式@BusinessActionContextParameter修饰的参数失效,无法在BusinessActionContext获取 [incubator-seata]
Posted by "Xiamu-ssr (via GitHub)" <gi...@apache.org>.
Xiamu-ssr closed issue #6235: 2.0.0 TCC模式@BusinessActionContextParameter修饰的参数失效,无法在BusinessActionContext获取
URL: https://github.com/apache/incubator-seata/issues/6235
--
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: dev-unsubscribe@seata.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@seata.apache.org
For additional commands, e-mail: dev-help@seata.apache.org