开发工具idea、jdk8,redis、maven
首先用idea搭建eureka-server
配置文件:
server.port=8761
eureka.instance.hostname=127.0.0.1
eureka.instance.prefer-ip-address=true
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
启动eureka-server
然后下载tx-lcn事务lcn4.1.0下载,选择-sprinfboot2.0.x分支进行下载
项目目录入上图,将该项目整体进行打包安装到maven本地仓库
找到刚下载的项目位置,进入到如图的目录文件夹内,按住ctrl+shift+鼠标右键 选择命令窗口,运行mvn package (maven环境变量要配置,否则找不到命令)这时maven会生成4.2.0版本的lcn
创建两个服务A,事务发起方
配置文件如下
eureka.client.serviceUrl.defaultZone= http://127.0.0.1:8761/eureka/
server.port= 8088
spring.application.name=service-hi
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=true
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/work?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.filters=stat,wall,log4j
mybatis.mapper-locations=classpath:mapper/*.xml
#Ribbon的负载均衡策略
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
ribbon.MaxAutoRetriesNextServer=0
#txmanager地址
tm.manager.url=http://127.0.0.1:9010/tx/manager/
logging.level.com.codingapi=debug
tm.manager.url为事务协调者服务的url
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.4.RELEASE
com.example
service1
0.0.1-SNAPSHOT
service1
Demo project for Spring Boot
1.8
Greenwich.SR1
4.2.0
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.0.1
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
org.springframework.cloud
spring-cloud-starter-netflix-zuul
org.springframework.cloud
spring-cloud-starter-openfeign
com.codingapi
tx-client
${lcn.last.version}
org.slf4j
*
com.codingapi
transaction-springcloud
${lcn.last.version}
org.slf4j
*
com.codingapi
tx-plugins-db
${lcn.last.version}
org.slf4j
*
org.projectlombok
lombok
true
mysql
mysql-connector-java
runtime
com.github.pagehelper
pagehelper
5.1.8
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
启动类,@EnableFeignClients注解一定要加扫描com.codingapi.tx包,否则因扫描不到jar内的feignclient导致报错
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
@EnableFeignClients(basePackages = {"com.example.service1.client","com.codingapi.tx"})
@MapperScan("com.example.service1.dao")
public class Service1Application {
public static void main(String[] args) {
SpringApplication.run(Service1Application.class, args);
}
}
@Autowired
private com.example.service1.client.TbUserService userService;
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
@TxTransaction(isStart = true)
@Transactional(rollbackFor = Exception.class)
@Override
public boolean deleteById(String id,String exFlag) {
int i = tbUserDao.deleteById(id);
Result del = userService.del("2");
int a = 1/0;
return true;
}
@FeignClient(value = "service-hi2",fallback = TbUserServiceImpl.class)
public interface TbUserService {
@RequestMapping(value = "/tbUser/del")
public Result del(String id);
@RequestMapping(value = "/tbUser/update")
public Result update(@RequestBody TbUserDTO userDTO);
}
class TbUserServiceImpl implements TbUserService{
@Override
public Result del(String id) {
return Result.error(10001,"请稍后重试");
}
@Override
public Result update(TbUserDTO userDTO) {
return Result.error(10001,"请稍后重试");
}
}
服务B,事务参与方
配置文件
eureka.client.serviceUrl.defaultZone= http://127.0.0.1:8761/eureka/
server.port= 8089
spring.application.name=service-hi2
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=true
feign.hystrix.enabled=true
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/work?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.filters=stat,wall,log4j
mybatis.mapper-locations=classpath:mapper/*.xml
#Ribbon的负载均衡策略
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
ribbon.MaxAutoRetriesNextServer=0
#txmanager地址
tm.manager.url=http://127.0.0.1:9010/tx/manager/
logging.level.com.codingapi=debug
pom文件同serviceA的pom文件
main方法
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
@EnableFeignClients(basePackages = {"com.example.service1.client","com.codingapi.tx"})
@MapperScan("com.example.service2.dao")
public class Service2Application {
public static void main(String[] args) {
SpringApplication.run(Service2Application.class, args);
}
}
feign调用http接口
/**
* 删除
* @param id
* @return
*/
@RequestMapping("/del")
@ResponseBody
public Result del(String id){
try {
tbUserService.deleteById("2");
}catch (Exception e){
return Result.ok(10001,"系统错误");
}
return Result.ok();
}
service:
*/
@TxTransaction
@Transactional(rollbackFor = Exception.class)
@Override
public boolean deleteById(String id) {
return tbUserDao.deleteById(id) > 0;
}
两个服务都配置好了,然后启动事务协调者,第一张图的tx-manager项目,启动成功后可以测试
结果,成功
两条数据都正常存在
eureka源码 :[email protected]:boss_along/lcn-eureka.git
serviceA服务发起方[email protected]:boss_along/lcn-service-a.git
serviceB服务参与方 [email protected]:boss_along/lcn-service-b.git