分布式事务不生效的问题,求助
版本号:
3.7.0
问题描述:
分布式事务
错误截图:
子模块数据库更新了,主模块抛出了异常,子模块的数据并没有回滚
这个是我seata的配置
下面这个是我主模块模拟的异常
下面是我子模块的代码
麻烦有大佬帮我分析下
友情提示:
- 未按格式要求发帖、描述过于简单的,会被直接删掉;
- 描述问题请图文并茂,方便我们理解并快速定位问题;
- 如果使用的不是master,请说明你使用的分支;
没看出来你两张图片的代码之间的关联关系, 另外需要提醒一点就是主模块的代码需要发起事务才行,主模块的事务传播到子模块中去才行。不能是光子模块有事务,而主模块却没有事务,那样就变成了普通的事务了,而不是分布式事务
主模块是发起了事务,而且主模块的事务id 子模块也能拿到,但是我主模块抛出异常后,子模块的数据并没有回滚
由于你提供的代码片段不具备参考性,很难帮你分析问题,请参考jeecgboot的中的分布式事务示例代码,我已测试过,是可以正常回滚的
我使用的是seata v1.7.0,jeecgboot 3.7.3, oracle 19c 亲测按照如下修改可以主事务,分支事务一起回滚 参考文章微服务项目中使用seata,以nacos作为配置中心,很详细
1、pom.xml添加依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.3.0.0</version>
</dependency>
2、依次按照下面的方式修改三个服务的application.yml
#logging:
# level:
# root: DEBUG
server:
port: 5002
spring:
application:
name: seata-account
main:
allow-bean-definition-overriding: true
autoconfigure:
# exclude: com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration
datasource:
dynamic:
primary: account # 设置默认数据源为 'master'
strict: false # 严格模式,如果找不到数据源是否报错
datasource:
account:
url: jdbc:oracle:thin:@localhost:1525/ORCLPDB1
username: seata_account
password: 123456
driver-class-name: oracle.jdbc.OracleDriver
seata: true
redis:
database: 0
host: 127.0.0.1
port: 6379
password: 123456
seata:
enable-auto-data-source-proxy: false
service:
grouplist:
default: 127.0.0.1:8091
vgroup-mapping:
springboot-seata-group: default
# seata 事务组编号 用于TC集群名
tx-service-group: springboot-seata-group
3、修改reduceBalance返回值 SeataAccountController.java
@PostMapping("/reduceBalance")
public Result reduceBalance(Long userId, BigDecimal amount) {
accountService.reduceBalance(userId, amount);
return Result.ok();
}
AccountClient.java
/**
* 扣减余额
* @param userId
* @param amount
* @return
*/
@PostMapping("/test/seata/account/reduceBalance")
Result reduceBalance(@RequestParam("userId") Long userId, @RequestParam("amount") BigDecimal amount);
SeataOrderServiceImpl.java
// 扣减库存并计算总价
BigDecimal amount = productClient.reduceStock(productId, count);
// 扣减余额
Result result = accountClient.reduceBalance(userId, amount);
// feign响应被二次封装,判断使主事务回滚
// JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(str));
if (result == null || !result.isSuccess()) {
throw new RuntimeException();
}
另外如果使用oracle数据库,undo_log建表语句如下:
CREATE TABLE undo_log (
id NUMBER(20) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL,
branch_id NUMBER(20) NOT NULL,
xid VARCHAR2(100) NOT NULL,
context VARCHAR2(128) NOT NULL,
rollback_info BLOB NOT NULL,
log_status NUMBER(11) NOT NULL,
log_created TIMESTAMP(6) NOT NULL,
log_modified TIMESTAMP(6) NOT NULL,
PRIMARY KEY (id)
);
ALTER TABLE undo_log ADD CONSTRAINT ux_undo_log UNIQUE (xid, branch_id);
CREATE SEQUENCE UNDO_LOG_SEQ START WITH 1 INCREMENT BY 1;