一、創建eureka注冊中心
a、pom文件

1 <properties> 2 <java.version>1.8</java.version> 3 <spring-cloud.version>Greenwich.SR2</spring-cloud.version> 4 </properties> 5 6 <dependencies> 7 <dependency> 8 <groupId>org.springframework.boot</groupId> 9 <artifactId>spring-boot-starter-web</artifactId> 10 </dependency> 11 <dependency> 12 <groupId>org.springframework.cloud</groupId> 13 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> 14 </dependency> 15 16 <dependency> 17 <groupId>org.springframework.boot</groupId> 18 <artifactId>spring-boot-starter-test</artifactId> 19 <scope>test</scope> 20 </dependency> 21 </dependencies> 22 23 <dependencyManagement> 24 <dependencies> 25 <dependency> 26 <groupId>org.springframework.cloud</groupId> 27 <artifactId>spring-cloud-dependencies</artifactId> 28 <version>${spring-cloud.version}</version> 29 <type>pom</type> 30 <scope>import</scope> 31 </dependency> 32 </dependencies> 33 </dependencyManagement>
b、properties文件
server.port=8761 #禁止將自己注冊到注冊中心 eureka.client.register-with-eureka=false eureka.instance.hostname=localhost eureka.client.fetch-registry=false eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/ eureka.server.enable-self-preservation=false spring.cloud.config.discovery.enabled=true
c、在啟動類上加上@EnableEurekaServer注解
@SpringBootApplication @EnableEurekaServer public class SpringcloudEurekaApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudEurekaApplication.class, args); } }
d、啟動該服務
二、創建微服務A
a、pom文件

1 <properties> 2 <java.version>1.8</java.version> 3 <spring-cloud.version>Greenwich.SR2</spring-cloud.version> 4 </properties> 5 6 <dependencies> 7 <dependency> 8 <groupId>org.springframework.boot</groupId> 9 <artifactId>spring-boot-starter-data-jpa</artifactId> 10 </dependency> 11 <dependency> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-web</artifactId> 14 </dependency> 15 <dependency> 16 <groupId>org.springframework.cloud</groupId> 17 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 18 </dependency> 19 20 <dependency> 21 <groupId>mysql</groupId> 22 <artifactId>mysql-connector-java</artifactId> 23 <scope>runtime</scope> 24 </dependency> 25 <dependency> 26 <groupId>org.springframework.boot</groupId> 27 <artifactId>spring-boot-starter-test</artifactId> 28 <scope>test</scope> 29 </dependency> 30 <dependency> 31 <groupId>com.alibaba</groupId> 32 <artifactId>druid</artifactId> 33 <version>1.0.9</version> 34 </dependency> 35 <dependency> 36 <groupId>org.springframework.cloud</groupId> 37 <artifactId>spring-cloud-starter-openfeign</artifactId> 38 </dependency> 39 </dependencies>
b、properties文件
spring.application.name=springcloud-aservice server.port=8080 eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ #spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.username=root spring.datasource.password=123456 spring.datasource.url=jdbc:mysql://localhost:3306/yzh?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true #################jpa配置#################### spring.jpa.database=mysql spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
c、在啟動類上添加@EnableEurekaClient注解
d、創建entity

1 @Entity 2 public class Orders implements Serializable{ 3 4 private static final long serialVersionUID = 3295617400035010415L; 5 6 @Id 7 @GeneratedValue(strategy = GenerationType.IDENTITY) 8 private Integer orderId; 9 10 private Integer itemId; 11 12 private Integer price; 13 14 public Integer getOrderId() { 15 return orderId; 16 } 17 18 public void setOrderId(Integer orderId) { 19 this.orderId = orderId; 20 } 21 22 public Integer getItemId() { 23 return itemId; 24 } 25 26 public void setItemId(Integer itemId) { 27 this.itemId = itemId; 28 } 29 30 public Integer getPrice() { 31 return price; 32 } 33 34 public void setPrice(Integer price) { 35 this.price = price; 36 } 37 }
e、創建dao
public interface OrderDao extends JpaRepository<Orders,Integer> { }
f、創建service

1 @Service 2 public class OrderService { 3 4 @Autowired 5 private OrderDao orderDao; 6 @Autowired 7 private InventoryService inventoryService; 8 9 @Transactional 10 public Orders addOrder(){ 11 Orders orders = new Orders(); 12 orders.setItemId(100); 13 orders.setPrice(2000); 14 15 Orders save = orderDao.save(orders); 16 17 inventoryService.updateInventory(100,9); 18 19 return save; 20 } 21 }
g、創建feign調用

1 @FeignClient(value = "springcloud-bservice",fallback = InventoryServiceFallback.class) 2 public interface InventoryService { 3 4 @GetMapping(value = "updateInventory") 5 Object updateInventory(@RequestParam(value = "itemId") Integer itemId,@RequestParam(value = "itemNum") Integer itemNum); 6 7 } 8 9 //回調類 10 public class InventoryServiceFallback implements InventoryService{ 11 @Override 12 public Object updateInventory(Integer itemId, Integer itemNum) { 13 return 0; 14 } 15 }
h、在啟動類上添加@EnableFeignClients注解
i、創建web
@RestController public class OrdersController { @Autowired private OrderService orderService; @RequestMapping("/addOrders") public Object addOrders(){ return orderService.addOrder(); } }
三、創建微服務B
a、pom文件

1 <properties> 2 <java.version>1.8</java.version> 3 <spring-cloud.version>Greenwich.SR2</spring-cloud.version> 4 </properties> 5 6 <dependencies> 7 <dependency> 8 <groupId>org.springframework.boot</groupId> 9 <artifactId>spring-boot-starter-data-jpa</artifactId> 10 </dependency> 11 <dependency> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-web</artifactId> 14 </dependency> 15 <dependency> 16 <groupId>org.springframework.cloud</groupId> 17 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 18 </dependency> 19 20 <dependency> 21 <groupId>mysql</groupId> 22 <artifactId>mysql-connector-java</artifactId> 23 <scope>runtime</scope> 24 </dependency> 25 <dependency> 26 <groupId>org.springframework.boot</groupId> 27 <artifactId>spring-boot-starter-test</artifactId> 28 <scope>test</scope> 29 </dependency> 30 </dependencies>
b、properties文件
spring.application.name=springcloud-bservice server.port=8081 eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ #spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.username=root spring.datasource.password=123456 spring.datasource.url=jdbc:mysql://localhost:3306/yzh?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true #################jpa配置#################### spring.jpa.database=mysql spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
c、在啟動類上添加@EnableEurekaClient注解
d、創建entity

1 @Entity 2 @Table(name = "tb_inventory") 3 public class TbInventory implements Serializable{ 4 private static final long serialVersionUID = 4171468306443543867L; 5 6 @Id 7 @GeneratedValue(strategy = GenerationType.IDENTITY) 8 private Integer inventoryId; 9 10 private Integer itemId; 11 12 private Integer itemnum; 13 14 public Integer getInventoryId() { 15 return inventoryId; 16 } 17 18 public void setInventoryId(Integer inventoryId) { 19 this.inventoryId = inventoryId; 20 } 21 22 public Integer getItemId() { 23 return itemId; 24 } 25 26 public void setItemId(Integer itemId) { 27 this.itemId = itemId; 28 } 29 30 public Integer getItemnum() { 31 return itemnum; 32 } 33 34 public void setItemnum(Integer itemnum) { 35 this.itemnum = itemnum; 36 } 37 }
e、創建dao
public interface TbInventoryDao extends JpaRepository<TbInventory,Integer> { }
f、創建service

1 @Service 2 public class TbInventoryService { 3 4 @Autowired 5 private TbInventoryDao tbInventoryDao; 6 7 8 @Transactional 9 public TbInventory updateInventory(Integer itemId,Integer itemNum){ 10 TbInventory tbInventory = new TbInventory(); 11 tbInventory.setItemId(itemId); 12 tbInventory.setItemnum(itemNum); 13 TbInventory save = tbInventoryDao.save(tbInventory); 14 System.err.println(1/0); 15 return save; 16 17 } 18 }
g、創建web
@RestController public class TbInventoryController { @Autowired private TbInventoryService tbInventoryService; @GetMapping("updateInventory") public Object updateInventory(@RequestParam Integer itemId, @RequestParam Integer itemNum){ return tbInventoryService.updateInventory(itemId,itemNum); } }
四、引入LCN
a、下載地址:https://github.com/codingapi/tx-lcn/releases
(此處下載的是版本5.0.2.RELEASE)
b、將項目txlcn-tm導入idea,並修改properties文件
spring.application.name=tx-manager server.port=7970 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tx-manager?characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=root mybatis.configuration.map-underscore-to-camel-case=true mybatis.configuration.use-generated-keys=true #tx-lcn.logger.enabled=true # TxManager Host Ip #tx-lcn.manager.host=127.0.0.1 # TxClient連接請求端口 #tx-lcn.manager.port=8070 # 心跳檢測時間(ms) #tx-lcn.manager.heart-time=15000 # 分布式事務執行總時間 #tx-lcn.manager.dtx-time=30000 #參數延遲刪除時間單位ms #tx-lcn.message.netty.attr-delay-time=10000 #tx-lcn.manager.concurrent-level=128 # 開啟日志 #tx-lcn.logger.enabled=true #logging.level.com.codingapi=debug #redis 主機 #spring.redis.host=127.0.0.1 #redis 端口 #spring.redis.port=6379 #redis 密碼 #spring.redis.password=
-
#
給出信息都是默認值
關於詳細配置說明見TM配置 -
application.properties 加載順序如下:
0、命令行啟動參數指定
1、file:./config/(當前jar目錄下的config目錄)
2、file:./(當前jar目錄)
3、classpath:/config/(classpath下的config目錄)
4、classpath:/(classpath根目錄)
發布的二進制可執行Jar包含一個默認配置文件(也就是4),可按需要覆蓋默認配置
c、創建MySQL數據庫, 名稱為: tx-manager、然后創建數據表
CREATE TABLE `t_tx_exception` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `group_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `unit_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `mod_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `transaction_state` tinyint(4) NULL DEFAULT NULL, `registrar` tinyint(4) NULL DEFAULT NULL, `remark` varchar(4096) NULL DEFAULT NULL, `ex_state` tinyint(4) NULL DEFAULT NULL COMMENT '0 未解決 1已解決', `create_time` datetime(0) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
d、將項目改造成springcloud項目,並注冊到eureka中

1 <properties> 2 <java.version>1.8</java.version> 3 <spring-cloud.version>Finchley.RELEASE</spring-cloud.version> 4 <spring-boot.version>2.1.7.RELEASE</spring-boot.version> 5 </properties> 6 7 <dependency> 8 <groupId>org.springframework.boot</groupId> 9 <artifactId>spring-boot-starter-data-redis</artifactId> 10 <version>${spring-boot.version}</version> 11 </dependency> 12 13 <dependency> 14 <groupId>org.springframework.boot</groupId> 15 <artifactId>spring-boot-starter-mail</artifactId> 16 <version>${spring-boot.version}</version> 17 </dependency> 18 <dependency> 19 <groupId>org.springframework.boot</groupId> 20 <artifactId>spring-boot-starter-data-jpa</artifactId> 21 <version>${spring-boot.version}</version> 22 </dependency> 23 <dependency> 24 <groupId>org.springframework.cloud</groupId> 25 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> 26 </dependency>
注意:為了防止版本沖突需要知道springboot的版本為2.1.x,並且設置springcloud的版本為Finchley.RELEASE,還要在properties文件中新增配置:spring.cloud.compatibility-verifier.enabled=false
c、將項目注冊到eureka中
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
d、在啟動類上添加@EnableEurekaClient注解
五、開始整合
a、在服務A、B的pom文件中引入坐標

1 <dependency> 2 <groupId>com.codingapi.txlcn</groupId> 3 <artifactId>txlcn-tc</artifactId> 4 <version>5.0.2.RELEASE</version> 5 <exclusions> 6 <exclusion> 7 <groupId>org.springframework.boot</groupId> 8 <artifactId>*</artifactId> 9 </exclusion> 10 </exclusions> 11 </dependency> 12 13 <dependency> 14 <groupId>com.codingapi.txlcn</groupId> 15 <artifactId>txlcn-txmsg-netty</artifactId> 16 <version>5.0.2.RELEASE</version> 17 <exclusions> 18 <exclusion> 19 <groupId>org.springframework.boot</groupId> 20 <artifactId>*</artifactId> 21 </exclusion> 22 </exclusions> 23 </dependency>
注意:為了防止springboot的jar包沖突,需要將里面關於springboot的所有jar包排除掉。
b、在服務A、B的啟動類上添加注解@EnableDistributedTransaction啟動分布式事務
c、在服務A中的需要分布式事務方法上面添加@LcnTransaction,服務B中添加@TxcTransaction注解。
六、啟動、測試
a、依次啟動eureka注冊中心,txlcn-tm,服務A、B
b、調用服務