diff --git a/examples/seata-example/account-service/pom.xml b/examples/seata-example/account-service/pom.xml
new file mode 100644
index 0000000..1d9b69f
--- /dev/null
+++ b/examples/seata-example/account-service/pom.xml
@@ -0,0 +1,25 @@
+
+
+ 4.0.0
+
+ com.chinaunicom.mall.ebtp.cloud
+ seata-example
+ 0.0.1-SNAPSHOT
+
+ com.chinaunicom.mall.ebtp.cloud
+ account-service
+ 0.0.1-SNAPSHOT
+ account-service
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/AccountSeataApplication.java b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/AccountSeataApplication.java
new file mode 100644
index 0000000..3989520
--- /dev/null
+++ b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/AccountSeataApplication.java
@@ -0,0 +1,20 @@
+package com.chinaunicom.mall.ebtp.cloud.account;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Import;
+
+import com.chinaunicom.mall.ebtp.cloud.eureka.starter.EurekaStarterConfiguration;
+
+@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
+@EnableFeignClients
+@Import(EurekaStarterConfiguration.class)
+public class AccountSeataApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(AccountSeataApplication.class, args);
+ }
+
+}
diff --git a/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/config/SeataDatasourceConfiguration.java b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/config/SeataDatasourceConfiguration.java
new file mode 100644
index 0000000..e14cb34
--- /dev/null
+++ b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/config/SeataDatasourceConfiguration.java
@@ -0,0 +1,42 @@
+package com.chinaunicom.mall.ebtp.cloud.account.config;
+
+import javax.sql.DataSource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+import com.alibaba.druid.pool.DruidDataSource;
+
+import io.seata.rm.datasource.DataSourceProxy;
+
+@Configuration
+public class SeataDatasourceConfiguration {
+
+ @Bean
+ @ConfigurationProperties(prefix = "spring.datasource")
+ public DataSource druidDataSource() {
+ return new DruidDataSource();
+ }
+
+ @Primary
+ @Bean("dataSource")
+ public DataSourceProxy dataSource(DataSource druidDataSource) {
+ return new DataSourceProxy(druidDataSource);
+ }
+
+ @Bean
+ public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy) throws Exception {
+ SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
+ sqlSessionFactoryBean.setDataSource(dataSourceProxy);
+ sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
+
+ return sqlSessionFactoryBean.getObject();
+
+ }
+
+}
diff --git a/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/controller/AccountController.java b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/controller/AccountController.java
new file mode 100644
index 0000000..06f7818
--- /dev/null
+++ b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/controller/AccountController.java
@@ -0,0 +1,24 @@
+package com.chinaunicom.mall.ebtp.cloud.account.controller;
+
+import java.math.BigDecimal;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.chinaunicom.mall.ebtp.cloud.account.service.AccountService;
+
+@RestController
+@RequestMapping("account")
+public class AccountController {
+
+ private @Autowired AccountService accountService;
+
+ @RequestMapping("decrease")
+ public String decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money) {
+ accountService.decrease(userId, money);
+ return "Account decrease success";
+ }
+
+}
diff --git a/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/entity/Account.java b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/entity/Account.java
new file mode 100644
index 0000000..67454ed
--- /dev/null
+++ b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/entity/Account.java
@@ -0,0 +1,21 @@
+package com.chinaunicom.mall.ebtp.cloud.account.entity;
+
+import java.math.BigDecimal;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@TableName
+@Accessors(chain = true)
+public class Account {
+
+ private Long id;
+ private Long userId;
+ private BigDecimal total;
+ private BigDecimal used;
+ private BigDecimal residue;
+
+}
diff --git a/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/feign/OrderApi.java b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/feign/OrderApi.java
new file mode 100644
index 0000000..837526d
--- /dev/null
+++ b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/feign/OrderApi.java
@@ -0,0 +1,16 @@
+package com.chinaunicom.mall.ebtp.cloud.account.feign;
+
+import java.math.BigDecimal;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient(value = "order-service")
+public interface OrderApi {
+
+ @RequestMapping("/order/update")
+ String update(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money,
+ @RequestParam("status") Integer status);
+
+}
diff --git a/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/mapper/AccountMapper.java b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/mapper/AccountMapper.java
new file mode 100644
index 0000000..f465201
--- /dev/null
+++ b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/mapper/AccountMapper.java
@@ -0,0 +1,18 @@
+package com.chinaunicom.mall.ebtp.cloud.account.mapper;
+
+import java.math.BigDecimal;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.chinaunicom.mall.ebtp.cloud.account.entity.Account;
+
+@Mapper
+public interface AccountMapper extends BaseMapper {
+
+ @Update("UPDATE account SET residue = residue - #{money}, used = used + #{money} WHERE user_id = #{userId}")
+ void decrease(@Param("userId") Long userId, @Param("money") BigDecimal money);
+
+}
diff --git a/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/service/AccountService.java b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/service/AccountService.java
new file mode 100644
index 0000000..a812435
--- /dev/null
+++ b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/service/AccountService.java
@@ -0,0 +1,9 @@
+package com.chinaunicom.mall.ebtp.cloud.account.service;
+
+import java.math.BigDecimal;
+
+public interface AccountService {
+
+ void decrease(Long userId, BigDecimal money);
+
+}
diff --git a/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/service/impl/AccountServiceImpl.java b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/service/impl/AccountServiceImpl.java
new file mode 100644
index 0000000..6f8d671
--- /dev/null
+++ b/examples/seata-example/account-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/account/service/impl/AccountServiceImpl.java
@@ -0,0 +1,38 @@
+package com.chinaunicom.mall.ebtp.cloud.account.service.impl;
+
+import java.math.BigDecimal;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.chinaunicom.mall.ebtp.cloud.account.feign.OrderApi;
+import com.chinaunicom.mall.ebtp.cloud.account.mapper.AccountMapper;
+import com.chinaunicom.mall.ebtp.cloud.account.service.AccountService;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Service
+public class AccountServiceImpl implements AccountService {
+
+ private @Autowired AccountMapper accountMapper;
+ private @Autowired OrderApi orderApi;
+
+ @Override
+ public void decrease(Long userId, BigDecimal money) {
+
+ log.info("--------> 扣减账户数据开始");
+
+ accountMapper.decrease(userId, money);
+
+ log.info("------->扣减账户结束account中");
+
+ log.info("修改订单状态开始");
+
+ String mes = orderApi.update(userId, money.multiply(new BigDecimal("0.09")), 0);
+
+ log.info("修改订单状态结束:{}", mes);
+
+ }
+
+}
diff --git a/examples/seata-example/account-service/src/main/reources/application-dev.yml b/examples/seata-example/account-service/src/main/reources/application-dev.yml
new file mode 100644
index 0000000..41fbbf9
--- /dev/null
+++ b/examples/seata-example/account-service/src/main/reources/application-dev.yml
@@ -0,0 +1,17 @@
+logging:
+ level:
+ com.chinaunicom.mall.ebtp.cloud: info
+
+server:
+ port: 8672
+
+spring:
+ cloud:
+ alibaba:
+ seata:
+ tx-service-group: test_tx_group
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://125.32.114.204:13306/ebtp_mall_bid?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
+ username: mall3-ebtp-dev
+ password: mall3-ebtp-dev
diff --git a/examples/seata-example/account-service/src/main/reources/application.yml b/examples/seata-example/account-service/src/main/reources/application.yml
new file mode 100644
index 0000000..c59b20c
--- /dev/null
+++ b/examples/seata-example/account-service/src/main/reources/application.yml
@@ -0,0 +1,6 @@
+spring:
+ profiles:
+ active: dev
+ application:
+ name: account-service
+
\ No newline at end of file
diff --git a/examples/seata-example/account-service/src/test/java/com/chinaunicom/mall/ebtp/cloud/account/AppTest.java b/examples/seata-example/account-service/src/test/java/com/chinaunicom/mall/ebtp/cloud/account/AppTest.java
new file mode 100644
index 0000000..67c932c
--- /dev/null
+++ b/examples/seata-example/account-service/src/test/java/com/chinaunicom/mall/ebtp/cloud/account/AppTest.java
@@ -0,0 +1,38 @@
+package com.chinaunicom.mall.ebtp.cloud.account;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/examples/seata-example/order-service/pom.xml b/examples/seata-example/order-service/pom.xml
new file mode 100644
index 0000000..fdf6947
--- /dev/null
+++ b/examples/seata-example/order-service/pom.xml
@@ -0,0 +1,25 @@
+
+
+ 4.0.0
+
+ com.chinaunicom.mall.ebtp.cloud
+ seata-example
+ 0.0.1-SNAPSHOT
+
+ com.chinaunicom.mall.ebtp.cloud
+ order-service
+ 0.0.1-SNAPSHOT
+ order-service
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/OrderSeataApplication.java b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/OrderSeataApplication.java
new file mode 100644
index 0000000..b9eb123
--- /dev/null
+++ b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/OrderSeataApplication.java
@@ -0,0 +1,18 @@
+package com.chinaunicom.mall.ebtp.cloud.order;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Import;
+
+import com.chinaunicom.mall.ebtp.cloud.eureka.starter.EurekaStarterConfiguration;
+
+@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
+@EnableFeignClients
+@Import(EurekaStarterConfiguration.class)
+public class OrderSeataApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(OrderSeataApplication.class, args);
+ }
+}
diff --git a/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/config/SeataDatasourceConfiguration.java b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/config/SeataDatasourceConfiguration.java
new file mode 100644
index 0000000..d9d3fad
--- /dev/null
+++ b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/config/SeataDatasourceConfiguration.java
@@ -0,0 +1,41 @@
+package com.chinaunicom.mall.ebtp.cloud.order.config;
+
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
+
+import io.seata.rm.datasource.DataSourceProxy;
+
+@Configuration
+public class SeataDatasourceConfiguration {
+
+ @Bean
+ @ConfigurationProperties(prefix = "spring.datasource")
+ public DataSource druidDataSource() {
+ return new DruidDataSource();
+ }
+
+ @Primary
+ @Bean("dataSource")
+ public DataSourceProxy dataSource(DataSource druidDataSource) {
+ return new DataSourceProxy(druidDataSource);
+ }
+
+ @Bean
+ @ConfigurationProperties(prefix = "mybatis")
+ public MybatisSqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("dataSource") DataSource dataSource) {
+ // 这里用 MybatisSqlSessionFactoryBean 代替了 SqlSessionFactoryBean,否则 MyBatisPlus 不会生效
+ MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
+ mybatisSqlSessionFactoryBean.setDataSource(dataSource);
+
+ return mybatisSqlSessionFactoryBean;
+ }
+
+}
diff --git a/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/controller/OrderController.java b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/controller/OrderController.java
new file mode 100644
index 0000000..ebca2ad
--- /dev/null
+++ b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/controller/OrderController.java
@@ -0,0 +1,34 @@
+package com.chinaunicom.mall.ebtp.cloud.order.controller;
+
+import java.math.BigDecimal;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.chinaunicom.mall.ebtp.cloud.order.entity.Order;
+import com.chinaunicom.mall.ebtp.cloud.order.service.OrderService;
+
+@RestController
+@RequestMapping("order")
+public class OrderController {
+
+ private @Autowired OrderService orderService;
+
+ @GetMapping("create")
+ public String create(@RequestBody Order order) {
+ orderService.create(order);
+ return "Create order success";
+ }
+
+ @RequestMapping("update")
+ String update(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money,
+ @RequestParam("status") Integer status) {
+ orderService.update(userId, money, status);
+ return "订单状态修改成功";
+ }
+
+}
diff --git a/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/entity/Order.java b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/entity/Order.java
new file mode 100644
index 0000000..1c0ef3b
--- /dev/null
+++ b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/entity/Order.java
@@ -0,0 +1,22 @@
+package com.chinaunicom.mall.ebtp.cloud.order.entity;
+
+import java.math.BigDecimal;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+@TableName("order_tbl")
+public class Order {
+
+ private Long id;
+ private Long userId;
+ private Long productId;
+ private Integer count;
+ private BigDecimal money;
+ private Integer status;
+
+}
diff --git a/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/feign/AccountApi.java b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/feign/AccountApi.java
new file mode 100644
index 0000000..8f6a788
--- /dev/null
+++ b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/feign/AccountApi.java
@@ -0,0 +1,15 @@
+package com.chinaunicom.mall.ebtp.cloud.order.feign;
+
+import java.math.BigDecimal;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient("account-service")
+public interface AccountApi {
+
+ @RequestMapping("/account/decrease")
+ String decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money);
+
+}
diff --git a/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/feign/StorageApi.java b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/feign/StorageApi.java
new file mode 100644
index 0000000..5aa0692
--- /dev/null
+++ b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/feign/StorageApi.java
@@ -0,0 +1,13 @@
+package com.chinaunicom.mall.ebtp.cloud.order.feign;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient("storage-service")
+public interface StorageApi {
+
+ @RequestMapping("/storage/decrease")
+ String decrease(@RequestParam("productId") Long productId, @RequestParam("count") Integer count);
+
+}
diff --git a/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/mapper/OrderMapper.java b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/mapper/OrderMapper.java
new file mode 100644
index 0000000..6320827
--- /dev/null
+++ b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/mapper/OrderMapper.java
@@ -0,0 +1,18 @@
+package com.chinaunicom.mall.ebtp.cloud.order.mapper;
+
+import java.math.BigDecimal;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.chinaunicom.mall.ebtp.cloud.order.entity.Order;
+
+@Mapper
+public interface OrderMapper extends BaseMapper {
+
+ @Update("UPDATE `order_tbl` SET money = money - #{money}, status = 1 WHERE user_id = #{userId} AND status = #{status};")
+ void update(@Param("userId") Long userId, @Param("money") BigDecimal money, @Param("status") Integer status);
+
+}
diff --git a/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/service/OrderService.java b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/service/OrderService.java
new file mode 100644
index 0000000..7ccc2d9
--- /dev/null
+++ b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/service/OrderService.java
@@ -0,0 +1,13 @@
+package com.chinaunicom.mall.ebtp.cloud.order.service;
+
+import java.math.BigDecimal;
+
+import com.chinaunicom.mall.ebtp.cloud.order.entity.Order;
+
+public interface OrderService {
+
+ void create(Order order);
+
+ void update(Long userId, BigDecimal money, Integer status);
+
+}
diff --git a/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/service/impl/OrderServiceImpl.java b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/service/impl/OrderServiceImpl.java
new file mode 100644
index 0000000..0297fbb
--- /dev/null
+++ b/examples/seata-example/order-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/order/service/impl/OrderServiceImpl.java
@@ -0,0 +1,49 @@
+package com.chinaunicom.mall.ebtp.cloud.order.service.impl;
+
+import java.math.BigDecimal;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.chinaunicom.mall.ebtp.cloud.order.entity.Order;
+import com.chinaunicom.mall.ebtp.cloud.order.feign.AccountApi;
+import com.chinaunicom.mall.ebtp.cloud.order.feign.StorageApi;
+import com.chinaunicom.mall.ebtp.cloud.order.mapper.OrderMapper;
+import com.chinaunicom.mall.ebtp.cloud.order.service.OrderService;
+
+import io.seata.spring.annotation.GlobalTransactional;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Service
+public class OrderServiceImpl implements OrderService {
+
+ private @Autowired OrderMapper orderMapper;
+ private @Autowired StorageApi storageApi;
+ private @Autowired AccountApi accountApi;
+
+ @Override
+ @GlobalTransactional(name = "fsp-create-order", rollbackFor = Exception.class)
+ public void create(Order order) {
+
+ log.info("-------->开始" + order);
+
+ orderMapper.insert(order);
+
+ // 扣减库存
+ storageApi.decrease(order.getProductId(), order.getCount());
+
+ log.info("-----------> 扣减账户开始");
+ accountApi.decrease(order.getUserId(), order.getMoney());
+ log.info("-----------> 扣减账户结束");
+
+ log.info("--------> 交易结束");
+ }
+
+ @Override
+ public void update(Long userId, BigDecimal money, Integer status) {
+ log.info("修改订单状态,入参为:userId={},money={},status={}", userId, money, status);
+ orderMapper.update(userId, money, status);
+ }
+
+}
diff --git a/examples/seata-example/order-service/src/main/resources/application-dev.yml b/examples/seata-example/order-service/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..8a65607
--- /dev/null
+++ b/examples/seata-example/order-service/src/main/resources/application-dev.yml
@@ -0,0 +1,18 @@
+logging:
+ level:
+ com.chinaunicom.mall.ebtp.cloud: info
+
+server:
+ port: 8673
+
+spring:
+ cloud:
+ alibaba:
+ seata:
+ tx-service-group: test_tx_group
+
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://125.32.114.204:13306/ebtp-cloud?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
+ username: mall3-ebtp-dev
+ password: mall3-ebtp-dev
diff --git a/examples/seata-example/order-service/src/main/resources/application.yml b/examples/seata-example/order-service/src/main/resources/application.yml
new file mode 100644
index 0000000..606750a
--- /dev/null
+++ b/examples/seata-example/order-service/src/main/resources/application.yml
@@ -0,0 +1,5 @@
+spring:
+ profiles:
+ active: dev
+ application:
+ name: order-service
\ No newline at end of file
diff --git a/examples/seata-example/order-service/src/test/java/com/chinaunicom/mall/ebtp/cloud/order/AppTest.java b/examples/seata-example/order-service/src/test/java/com/chinaunicom/mall/ebtp/cloud/order/AppTest.java
new file mode 100644
index 0000000..715c181
--- /dev/null
+++ b/examples/seata-example/order-service/src/test/java/com/chinaunicom/mall/ebtp/cloud/order/AppTest.java
@@ -0,0 +1,23 @@
+package com.chinaunicom.mall.ebtp.cloud.order;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.chinaunicom.mall.ebtp.cloud.order.entity.Order;
+import com.chinaunicom.mall.ebtp.cloud.order.mapper.OrderMapper;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class AppTest {
+ private @Autowired OrderMapper orderMapper;
+
+// @Test
+ public void testInsert() {
+ Order order = new Order();
+
+ orderMapper.insert(order);
+ }
+}
diff --git a/examples/seata-example/pom.xml b/examples/seata-example/pom.xml
new file mode 100644
index 0000000..9668844
--- /dev/null
+++ b/examples/seata-example/pom.xml
@@ -0,0 +1,59 @@
+
+
+ 4.0.0
+
+ com.chinaunicom.ebtp
+ mall-ebtp-cloud-parent
+ 0.0.1
+
+
+ com.chinaunicom.mall.ebtp.cloud
+ seata-example
+ 0.0.1-SNAPSHOT
+ pom
+
+ seata-example
+ http://maven.apache.org
+
+
+ UTF-8
+
+
+
+
+ com.chinaunicom.ebtp
+ mall-ebtp-cloud-eureka-starter
+
+
+ com.chinaunicom.ebtp
+ mall-ebtp-cloud-jpa-starter
+
+
+ com.chinaunicom.ebtp
+ mall-ebtp-cloud-feign-starter
+
+
+ mysql
+ mysql-connector-java
+
+
+ com.alibaba.cloud
+ spring-cloud-alibaba-seata
+
+
+ seata-all
+ io.seata
+
+
+
+
+ io.seata
+ seata-all
+
+
+
+ storage-service
+ order-service
+ account-service
+
+
\ No newline at end of file
diff --git a/examples/seata-example/storage-service/pom.xml b/examples/seata-example/storage-service/pom.xml
new file mode 100644
index 0000000..ba2aab1
--- /dev/null
+++ b/examples/seata-example/storage-service/pom.xml
@@ -0,0 +1,24 @@
+
+
+ 4.0.0
+
+ com.chinaunicom.mall.ebtp.cloud
+ seata-example
+ 0.0.1-SNAPSHOT
+
+ com.chinaunicom.mall.ebtp.cloud
+ storage-service
+ 0.0.1-SNAPSHOT
+ storage-service
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/StorageSeataApplication.java b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/StorageSeataApplication.java
new file mode 100644
index 0000000..b55f569
--- /dev/null
+++ b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/StorageSeataApplication.java
@@ -0,0 +1,18 @@
+package com.chinaunicom.mall.ebtp.cloud.storage;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Import;
+
+import com.chinaunicom.mall.ebtp.cloud.eureka.starter.EurekaStarterConfiguration;
+
+@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
+@EnableFeignClients
+@Import(EurekaStarterConfiguration.class)
+public class StorageSeataApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(StorageSeataApplication.class, args);
+ }
+}
diff --git a/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/config/SeataDatasourceConfiguration.java b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/config/SeataDatasourceConfiguration.java
new file mode 100644
index 0000000..e797709
--- /dev/null
+++ b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/config/SeataDatasourceConfiguration.java
@@ -0,0 +1,42 @@
+package com.chinaunicom.mall.ebtp.cloud.storage.config;
+
+import javax.sql.DataSource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+import com.alibaba.druid.pool.DruidDataSource;
+
+import io.seata.rm.datasource.DataSourceProxy;
+
+@Configuration
+public class SeataDatasourceConfiguration {
+
+ @Bean
+ @ConfigurationProperties(prefix = "spring.datasource")
+ public DataSource druidDataSource() {
+ return new DruidDataSource();
+ }
+
+ @Primary
+ @Bean("dataSource")
+ public DataSourceProxy dataSource(DataSource druidDataSource) {
+ return new DataSourceProxy(druidDataSource);
+ }
+
+ @Bean
+ public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy) throws Exception {
+ SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
+ sqlSessionFactoryBean.setDataSource(dataSourceProxy);
+ sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
+
+ return sqlSessionFactoryBean.getObject();
+
+ }
+
+}
diff --git a/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/controller/StorageController.java b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/controller/StorageController.java
new file mode 100644
index 0000000..54774f2
--- /dev/null
+++ b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/controller/StorageController.java
@@ -0,0 +1,22 @@
+package com.chinaunicom.mall.ebtp.cloud.storage.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.chinaunicom.mall.ebtp.cloud.storage.service.StorageService;
+
+@RestController
+@RequestMapping("storage")
+public class StorageController {
+
+ private @Autowired StorageService storageService;
+
+ @RequestMapping("decrease")
+ public String decrease(@RequestParam("productId") Long productId, @RequestParam("count") Integer count) {
+ storageService.decrease(productId, count);
+ return "Decrease Storage success";
+ }
+
+}
diff --git a/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/entity/Storage.java b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/entity/Storage.java
new file mode 100644
index 0000000..ac2892c
--- /dev/null
+++ b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/entity/Storage.java
@@ -0,0 +1,19 @@
+package com.chinaunicom.mall.ebtp.cloud.storage.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@TableName
+@Accessors(chain = true)
+public class Storage {
+
+ private Long id;
+ private Long productId;
+ private Integer total;
+ private Integer used;
+ private Integer residue;
+
+}
diff --git a/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/mapper/StorageMapper.java b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/mapper/StorageMapper.java
new file mode 100644
index 0000000..6469791
--- /dev/null
+++ b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/mapper/StorageMapper.java
@@ -0,0 +1,16 @@
+package com.chinaunicom.mall.ebtp.cloud.storage.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.chinaunicom.mall.ebtp.cloud.storage.entity.Storage;
+
+@Mapper
+public interface StorageMapper extends BaseMapper {
+
+ @Update("UPDATE storage SET used = used + #{count}, residue = residue - #{count} WHERE product_id = #{productId}")
+ void decrease(@Param("productId") Long productId, @Param("count") Integer count);
+
+}
diff --git a/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/service/StorageService.java b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/service/StorageService.java
new file mode 100644
index 0000000..7abb4ec
--- /dev/null
+++ b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/service/StorageService.java
@@ -0,0 +1,7 @@
+package com.chinaunicom.mall.ebtp.cloud.storage.service;
+
+public interface StorageService {
+
+ void decrease(Long productId, Integer count);
+
+}
diff --git a/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/service/impl/StorageServiceImpl.java b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/service/impl/StorageServiceImpl.java
new file mode 100644
index 0000000..ca361f0
--- /dev/null
+++ b/examples/seata-example/storage-service/src/main/java/com/chinaunicom/mall/ebtp/cloud/storage/service/impl/StorageServiceImpl.java
@@ -0,0 +1,24 @@
+package com.chinaunicom.mall.ebtp.cloud.storage.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.chinaunicom.mall.ebtp.cloud.storage.mapper.StorageMapper;
+import com.chinaunicom.mall.ebtp.cloud.storage.service.StorageService;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Service
+public class StorageServiceImpl implements StorageService {
+
+ private @Autowired StorageMapper storageMapper;
+
+ @Override
+ public void decrease(Long productId, Integer count) {
+ log.info("------->扣减库存开始");
+ storageMapper.decrease(productId, count);
+ log.info("------->扣减库存结束");
+ }
+
+}
diff --git a/examples/seata-example/storage-service/src/main/resources/application-dev.yml b/examples/seata-example/storage-service/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..17b4e62
--- /dev/null
+++ b/examples/seata-example/storage-service/src/main/resources/application-dev.yml
@@ -0,0 +1,18 @@
+logging:
+ level:
+ com.chinaunicom.mall.ebtp.cloud: info
+
+server:
+ port: 8674
+
+spring:
+ cloud:
+ alibaba:
+ seata:
+ tx-service-group: test_tx_group
+
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://125.32.114.204:13306/ebtp_mall_evaluation?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
+ username: mall3-ebtp-dev
+ password: mall3-ebtp-dev
diff --git a/examples/seata-example/storage-service/src/main/resources/application.yml b/examples/seata-example/storage-service/src/main/resources/application.yml
new file mode 100644
index 0000000..cd51a7a
--- /dev/null
+++ b/examples/seata-example/storage-service/src/main/resources/application.yml
@@ -0,0 +1,5 @@
+spring:
+ profiles:
+ active: dev
+ application:
+ name: storage-service
\ No newline at end of file
diff --git a/examples/seata-example/storage-service/src/test/java/com/chinaunicom/mall/ebtp/cloud/storage/AppTest.java b/examples/seata-example/storage-service/src/test/java/com/chinaunicom/mall/ebtp/cloud/storage/AppTest.java
new file mode 100644
index 0000000..2162ea7
--- /dev/null
+++ b/examples/seata-example/storage-service/src/test/java/com/chinaunicom/mall/ebtp/cloud/storage/AppTest.java
@@ -0,0 +1,38 @@
+package com.chinaunicom.mall.ebtp.cloud.storage;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/mall-ebtp-cloud-feign-starter/src/main/resources/feign-configuration.properties b/mall-ebtp-cloud-feign-starter/src/main/resources/feign-configuration.properties
index 2f48da2..9135922 100644
--- a/mall-ebtp-cloud-feign-starter/src/main/resources/feign-configuration.properties
+++ b/mall-ebtp-cloud-feign-starter/src/main/resources/feign-configuration.properties
@@ -1,2 +1,4 @@
# 默认开启熔断
-feign.hystrix.enabled=true
\ No newline at end of file
+feign.hystrix.enabled=true
+feign.client.config.default.connectTimeout=5000
+feign.client.config.default.readTimeout=10000
\ No newline at end of file
diff --git a/mall-ebtp-cloud-jpa-starter/src/main/resoureces/file.conf b/mall-ebtp-cloud-jpa-starter/src/main/resoureces/file.conf
new file mode 100644
index 0000000..a37e3e2
--- /dev/null
+++ b/mall-ebtp-cloud-jpa-starter/src/main/resoureces/file.conf
@@ -0,0 +1,66 @@
+transport {
+ # tcp udt unix-domain-socket
+ type = "TCP"
+ #NIO NATIVE
+ server = "NIO"
+ #enable heartbeat
+ heartbeat = true
+ # the client batch send request enable
+ enableClientBatchSendRequest = true
+ #thread factory for netty
+ threadFactory {
+ bossThreadPrefix = "NettyBoss"
+ workerThreadPrefix = "NettyServerNIOWorker"
+ serverExecutorThread-prefix = "NettyServerBizHandler"
+ shareBossWorker = false
+ clientSelectorThreadPrefix = "NettyClientSelector"
+ clientSelectorThreadSize = 1
+ clientWorkerThreadPrefix = "NettyClientWorkerThread"
+ # netty boss thread size,will not be used for UDT
+ bossThreadSize = 1
+ #auto default pin or 8
+ workerThreadSize = "default"
+ }
+ shutdown {
+ # when destroy server, wait seconds
+ wait = 3
+ }
+ serialization = "seata"
+ compressor = "none"
+}
+service {
+ #transaction service group mapping
+ vgroupMapping.test_tx_group = "default"
+ #only support when registry.type=file, please don't set multiple addresses
+ default.grouplist = "127.0.0.1:8091"
+ #degrade, current not support
+ enableDegrade = false
+ #disable seata
+ disableGlobalTransaction = false
+}
+
+client {
+ rm {
+ asyncCommitBufferLimit = 10000
+ lock {
+ retryInterval = 10
+ retryTimes = 30
+ retryPolicyBranchRollbackOnConflict = true
+ }
+ reportRetryCount = 5
+ tableMetaCheckEnable = false
+ reportSuccessEnable = false
+ }
+ tm {
+ commitRetryCount = 5
+ rollbackRetryCount = 5
+ }
+ undo {
+ dataValidation = true
+ logSerialization = "jackson"
+ logTable = "undo_log"
+ }
+ log {
+ exceptionRate = 100
+ }
+}
\ No newline at end of file
diff --git a/mall-ebtp-cloud-jpa-starter/src/main/resoureces/registry.conf b/mall-ebtp-cloud-jpa-starter/src/main/resoureces/registry.conf
new file mode 100644
index 0000000..4694f23
--- /dev/null
+++ b/mall-ebtp-cloud-jpa-starter/src/main/resoureces/registry.conf
@@ -0,0 +1,17 @@
+registry {
+ type = "eureka"
+
+ eureka {
+ serviceUrl = "http://192.168.40.17:12093/eureka/,http://192.168.40.17:18126/eureka/,http://192.168.40.17:28641/eureka/"
+ application = "default"
+ weight = "1"
+ }
+}
+
+config {
+ type = "file"
+
+ file {
+ name = "file.conf"
+ }
+}
diff --git a/mall-ebtp-cloud-parent/pom.xml b/mall-ebtp-cloud-parent/pom.xml
index 3ce3561..19ed992 100644
--- a/mall-ebtp-cloud-parent/pom.xml
+++ b/mall-ebtp-cloud-parent/pom.xml
@@ -25,6 +25,7 @@
1.1.14
2.0.3
5.4.1
+ 1.3.0
@@ -49,11 +50,11 @@
unifast-storage
1.0.0
-
- p6spy
- p6spy
- 3.8.5
-
+
+ p6spy
+ p6spy
+ 3.8.5
+
commons-fileupload
commons-fileupload
@@ -193,6 +194,17 @@
apm-toolkit-trace
8.1.0
+
+
+ com.alibaba.cloud
+ spring-cloud-alibaba-seata
+ 2.1.0.RELEASE
+
+
+ io.seata
+ seata-all
+ ${seata.version}
+