前言
Github:https://github.com/HealerJean
1、開始Demo
1.1、hlj-02-vertical_shard.sql
drop database if exists ds_0;
create database ds_0 character set 'utf8' collate 'utf8_general_ci';
use ds_0;
drop table if exists user;
create table `user`
(
`id` bigint(20) unsigned not null,
city varchar(20) not null default '',
name varchar(20) not null default '',
status int(10) not null default '0' comment '狀態',
create_time datetime not null default current_timestamp comment '創建時間',
update_time datetime not null default current_timestamp on update current_timestamp comment '修改時間',
primary key (`id`)
) engine = innodb
default charset = utf8;
create table `demo_entity`
(
`id` bigint(20) unsigned not null comment '主鍵',
`name` varchar(64) not null,
`phone` varchar(20) default '' comment '手機號',
`email` varchar(64) default '' comment '郵箱',
`age` int(10) default null,
`status` varchar(8) not null comment '狀態',
`create_user` bigint(16) unsigned default null comment '創建人',
`create_name` varchar(64) default '' comment '創建人名稱',
`create_time` datetime not null default current_timestamp comment '創建時間',
`update_user` bigint(16) unsigned default null comment '更新人',
`update_name` varchar(64) default '' comment '更新人名稱',
`update_time` datetime not null default current_timestamp on update current_timestamp comment '更新時間',
primary key (`id`)
) engine = innodb
default charset = utf8;
drop database if exists ds_1;
create database `ds_1` character set 'utf8' collate 'utf8_general_ci';
use ds_1;
drop table if exists company;
create table `company`
(
`id` bigint(20) unsigned not null comment '主鍵',
name varchar(20) not null default '' comment '企業名稱',
company_name_english varchar(128) not null default '' comment '企業英文名稱',
status int(10) not null default '0' comment '狀態',
create_time datetime not null default current_timestamp comment '創建時間',
update_time datetime not null default current_timestamp on update current_timestamp comment '修改時間',
primary key (`id`)
) engine = innodb
default charset = utf8;
1.1.1、數據庫圖文
1.2、依賴
<!--shardingsphere-->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
1.3、配置文件:application.properties
server.port=8888
# 配置 mybatis的一些配置,也可以在 application.properties 中配置,如果配置了就不需要了mybatis.xml
#mybatis-plus.config-location=classpath:mybatis.xml
#Maven 多模塊項目的掃描路徑需以 classpath*: 開頭 (即加載多個 jar 包下的 XML 文件)
mybatis-plus.mapper-locations=classpath*:mapper/*.xml
mybatis-plus.type-aliases-package=com.healerjean.proj.pojo
##主鍵類型 0:"數據庫ID自增,非常大", 1:"用戶輸入ID(如果用戶不輸入,則默認是0)",2:"全局唯一ID (數字類型唯一ID)", 3:"全局唯一ID UUID";
mybatis-plus.id-type: 0
#字段策略 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷"
mybatis-plus.field-strategy: 2
#數據庫大寫下劃線轉換
mybatis-plus.capital-mode: true
mybatis-plus.refresh-mapper: true
# 垂直拆分(不同的表在不同的庫中)
spring.shardingsphere.datasource.names=ds0,ds1
# #當遇到同樣名字的時候,是否允許覆蓋註冊
spring.main.allow-bean-definition-overriding=true
# 顯示SQL
spring.shardingsphere.props.sql.show=true
# 不會指定默認數據源。查詢的時候會隨機指定一個,如果表不存在會報錯,插入的時候,會報錯,提示沒有數據源(如下)
### Error updating database. Cause: java.lang.IllegalStateException: Missing the data source name: 'null'
### The error may exist in com/healerjean/proj/dao/mapper/DemoEntityMapper.java (best guess)
### The error may involve com.healerjean.proj.dao.mapper.DemoEntityMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO demo_entity ( id, name, phone, status ) VALUES ( ?, ?, ?, ? )
### Cause: java.lang.IllegalStateException: Missing the data source name: 'null'
# 數據源,
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/ds_0?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://localhost:3306/ds_1?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
# 綁定company表所在庫
spring.shardingsphere.sharding.tables.company.actual-data-nodes=ds1.company
# 綁定user表所在庫
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds0.user
# 使用mybatis-plus的 id策略,不用下面的
# 設置自增ID
#spring.shardingsphere.sharding.tables.user.key-generator.column=id
# 設置自增ID算法
#spring.shardingsphere.sharding.tables.user.key-generator.type=SNOWFLAKE
1.4、具體測試方法和類
1.4.1、實體類
1.4.1.1、User.java
@Data
@Accessors(chain = true)
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/** 主鍵 */
private Long id;
private String name;
private String city;
private String status;
private Date createTime;
private Date updateTime;
}
1.4.1.2、Company.java
@Data
public class Company {
private Long id;
private String name;
private String companyNameEnglish;
private String status;
private Date createTime;
private Date updateTime;
}
1.4.1.3、DemoEntity.java
@Data
@Accessors(chain = true)
public class DemoEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主鍵
*/
private Long id;
/** 姓名 */
private String name;
/** 手機號 */
private String phone;
/** 郵箱 */
private String email;
/** 年齡 */
private Integer age;
/** 10可用,99刪除 */
private String status;
/** 創建人 */
private Long createUser;
/** 創建人名稱 */
private String createName;
/** 創建時間 */
private java.util.Date createTime;
/** 更新人 */
private Long updateUser;
/** 更新人名稱 */
private String updateName;
/** 更新時間 */
private java.util.Date updateTime;
}
1.4.2、DTO數據
1.4.2.1、UserDTO.java
@Data
@Accessors(chain = true)
@ApiModel(value = "demo實體類")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserDTO {
@ApiModelProperty(value = "主鍵", hidden = true)
@JsonSerialize(using = JsonLongSerializer.class )
private Long id;
@ApiModelProperty(value = "姓名")
@NotBlank(message = "姓名不能爲空", groups = ValidateGroup.HealerJean.class)
private String name;
@ApiModelProperty(value = "城市")
private String city;
@ApiModelProperty(value = "狀態", hidden = true)
private String status;
@ApiModelProperty(value = "創建時間", hidden = true)
@JsonFormat(pattern = DateUtils.YYYY_MM_dd_HH_mm_ss, timezone = "GMT+8")
private Date createTime;
@ApiModelProperty(value = "修改時間", hidden = true)
@JsonFormat(pattern = DateUtils.YYYY_MM_dd_HH_mm_ss, timezone = "GMT+8")
private Date updateTime;
}
1.4.2.2、CompanyDTO.java
@Data
public class CompanyDTO {
@JsonSerialize(using = JsonLongSerializer.class )
private Long id;
private String name;
private String companyNameEnglish;
private String status;
@ApiModelProperty(value = "創建時間", hidden = true)
@JsonFormat(pattern = DateUtils.YYYY_MM_dd_HH_mm_ss, timezone = "GMT+8")
private Date createTime;
@ApiModelProperty(value = "修改時間", hidden = true)
@JsonFormat(pattern = DateUtils.YYYY_MM_dd_HH_mm_ss, timezone = "GMT+8")
private Date updateTime;
}
1.4.2.3、DemoDTO.java
@Data
@Accessors(chain = true)
@ApiModel(value = "demo實體類")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DemoDTO extends PageQuery {
@JsonSerialize(using = JsonLongSerializer.class )
private Long id;
@ApiModelProperty(value = "姓名")
@NotBlank(message = "姓名不能爲空", groups = ValidateGroup.HealerJean.class)
private String name;
@ApiModelProperty(value = "年齡")
private Integer age;
@ApiModelProperty(value = "手機號")
private String phone;
@ApiModelProperty(value = "郵箱")
private String email;
@ApiModelProperty(value = "是否刪除,10可用,99刪除 ", hidden = true)
private String status;
@ApiModelProperty(value = "創建人", hidden = true)
private Long createUser;
@ApiModelProperty(value = "創建人名字", hidden = true)
private String createName;
@ApiModelProperty(value = "創建時間", hidden = true)
private java.util.Date createTime;
@ApiModelProperty(value = "更新人", hidden = true)
private Long updateUser;
@ApiModelProperty(value = "更新人名稱", hidden = true)
private String updateName;
@ApiModelProperty(hidden = true)
private java.util.Date updateTime;
}
1.4.3、Mapper
1.4.3.1、UserMapper.java
public interface UserMapper extends BaseMapper<User> {
}
1.4.3.1、CompanyMapper.java
public interface CompanyMapper extends BaseMapper<Company> {
}
1.4.3.1、DemoEntityMapper.java
public interface DemoEntityMapper extends BaseMapper<DemoEntity> {
}
1.4.4、Service
1.4.4.1、 UserService.java
public interface UserService {
UserDTO insert(UserDTO userDTO);
UserDTO findById(Long id);
List<UserDTO> list();
}
1.4.4.2、 CompanyService.java
public interface CompanyService {
CompanyDTO insert(CompanyDTO companyDTO);
CompanyDTO findById(Long id);
List<CompanyDTO> list();
}
1.4.4.3、 DemoEntityService.java
public interface DemoEntityService {
DemoDTO insert(DemoDTO demoEntity);
DemoDTO findById(Long id);
List<DemoDTO> list();
/**
* 測試多個數據庫事務
*/
void dbTransactional(UserDTO userDTO, CompanyDTO companyDTO);
}
1.4.5、ServiceImpl.java
1.4.5.1、UserServiceImpl.java
@Service
@Slf4j
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Override
public UserDTO insert(UserDTO userDTO) {
User user = BeanUtils.dtoToUserDTO(userDTO);
user.setStatus(StatusEnum.生效.code);
userMapper.insert(user);
userDTO.setId(user.getId());
return userDTO;
}
@Override
public UserDTO findById(Long id) {
User user = userMapper.selectById(id);
return user == null ? null : BeanUtils.userToDTO(user);
}
@Override
public List<UserDTO> list() {
List<User> users = userMapper.selectList(null);
List<UserDTO> list = null;
if (!EmptyUtil.isEmpty(users)) {
list = users.stream().map(BeanUtils::userToDTO).collect(Collectors.toList());
}
return list;
}
}
1.4.5.2、CompanyServiceImpl.java
@Service
public class CompanyServiceImpl implements CompanyService {
@Resource
private CompanyMapper companyMapper;
@Override
public CompanyDTO insert(CompanyDTO companyDTO) {
Company company = BeanUtils.dtoToCompany(companyDTO);
company.setStatus(StatusEnum.生效.code);
companyMapper.insert(company);
companyDTO.setId(company.getId());
return companyDTO;
}
@Override
public CompanyDTO findById(Long id) {
Company company = companyMapper.selectById(id);
return company == null ? null : BeanUtils.companyToDTO(company);
}
@Override
public List<CompanyDTO> list() {
List<Company> companys = companyMapper.selectList(null);
List<CompanyDTO> list = null;
if (!EmptyUtil.isEmpty(companys)) {
list = companys.stream().map(BeanUtils::companyToDTO).collect(Collectors.toList());
}
return list;
}
}
1.4.5.3、DemoEntityServiceImpl.java
@Service
@Slf4j
public class DemoEntityServiceImpl implements DemoEntityService {
@Resource
private DemoEntityMapper demoEntityMapper;
@Resource
private CompanyService companyService;
@Resource
private UserService userService;
@Override
public DemoDTO insert(DemoDTO demoDTO) {
DemoEntity demoEntity = BeanUtils.dtoToDemo(demoDTO);
demoEntity.setStatus(StatusEnum.生效.code);
demoEntityMapper.insert(demoEntity);
demoDTO.setId(demoEntity.getId());
return demoDTO;
}
@Override
public DemoDTO findById(Long id) {
DemoEntity demoEntity = demoEntityMapper.selectById(id);
return demoEntity == null ? null : BeanUtils.demoToDTO(demoEntity);
}
@Override
public List<DemoDTO> list() {
List<DemoDTO> collect = null;
List<DemoEntity> list = demoEntityMapper.selectList(null);
if (!EmptyUtil.isEmpty(list)) {
collect = list.stream().map(BeanUtils::demoToDTO).collect(Collectors.toList());
}
return collect;
}
/**
* 分庫分表也是有事務的,如果跑出了異常,則都不能成功
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void dbTransactional(UserDTO userDTO, CompanyDTO companyDTO) {
userService.insert(userDTO);
companyService.insert(companyDTO);
int i = 1/0;
}
}
1.4.6、Controller
1.4.6.1、UserController.java
@ApiResponses(value = {
@ApiResponse(code = 200, message = "訪問正常"),
@ApiResponse(code = 301, message = "邏輯錯誤"),
@ApiResponse(code = 500, message = "系統錯誤"),
@ApiResponse(code = 401, message = "未認證"),
@ApiResponse(code = 403, message = "禁止訪問"),
@ApiResponse(code = 404, message = "url錯誤")
})
@Api(description = "demo控制器")
@Controller
@RequestMapping("hlj/demo")
@Slf4j
public class UserController {
@Autowired
private UserService userService;
@ApiOperation(value = "insert",
notes = "insert",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
response = UserDTO.class)
@PostMapping(value = "insert", produces = "application/json; charset=utf-8")
@ResponseBody
public ResponseBean insert(UserDTO userDTO) {
log.info("樣例--------mybaits-plus添加demo實體------數據信息{}", userDTO);
String validate = ValidateUtils.validate(userDTO, ValidateGroup.HealerJean.class);
if (!validate.equals(CommonConstants.COMMON_SUCCESS)) {
throw new BusinessException(ResponseEnum.參數錯誤, validate);
}
return ResponseBean.buildSuccess(userService.insert(userDTO));
}
@ApiOperation(notes = "findById",
value = "findById",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
response = UserDTO.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "demo主鍵", required = true, paramType = "path", dataType = "long"),
})
@GetMapping("findById/{id}")
@ResponseBody
public ResponseBean findById(@PathVariable Long id) {
log.info("樣例--------findById------數據:id:{}", id);
return ResponseBean.buildSuccess(userService.findById(id));
}
@ApiOperation(notes = "list",
value = "list",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
response = UserDTO.class)
@GetMapping("list")
@ResponseBody
public ResponseBean list() {
log.info("樣例--------list------");
return ResponseBean.buildSuccess(userService.list());
}
}
1.4.6.2、CompanyController.java
@ApiResponses(value = {
@ApiResponse(code = 200, message = "訪問正常"),
@ApiResponse(code = 301, message = "邏輯錯誤"),
@ApiResponse(code = 500, message = "系統錯誤"),
@ApiResponse(code = 401, message = "未認證"),
@ApiResponse(code = 403, message = "禁止訪問"),
@ApiResponse(code = 404, message = "url錯誤")
})
@Api(description = "demo控制器")
@Controller
@RequestMapping("hlj/company")
@Slf4j
public class CompanyController {
@Autowired
private CompanyService companyService;
@ApiOperation(value = "insert",
notes = "insert",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
response = UserDTO.class)
@PostMapping(value = "insert", produces = "application/json; charset=utf-8")
@ResponseBody
public ResponseBean insert(CompanyDTO companyDTO) {
log.info("user--------insert------請求參數:{}", companyDTO);
return ResponseBean.buildSuccess(companyService.insert(companyDTO));
}
@ApiOperation(notes = "findById",
value = "findById",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
response = UserDTO.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "demo主鍵", required = true, paramType = "path", dataType = "long"),
})
@GetMapping("findById/{id}")
@ResponseBody
public ResponseBean findById(@PathVariable Long id) {
log.info("company--------findById------id:{}", id);
return ResponseBean.buildSuccess(companyService.findById(id));
}
@ApiOperation(notes = "list",
value = "list",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
response = UserDTO.class)
@GetMapping("list")
@ResponseBody
public ResponseBean list() {
log.info("company--------list------");
return ResponseBean.buildSuccess(companyService.list());
}
}
1.4.6.3、DemoController.java
@ApiResponses(value = {
@ApiResponse(code = 200, message = "訪問正常"),
@ApiResponse(code = 301, message = "邏輯錯誤"),
@ApiResponse(code = 500, message = "系統錯誤"),
@ApiResponse(code = 401, message = "未認證"),
@ApiResponse(code = 403, message = "禁止訪問"),
@ApiResponse(code = 404, message = "url錯誤")
})
@Api(description = "demo控制器")
@Controller
@RequestMapping("hlj/demo")
@Slf4j
public class DemoController {
@Autowired
private DemoEntityService demoEntityService;
@ApiOperation(value = "insert",
notes = "insert",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
response = UserDTO.class)
@PostMapping(value = "insert", produces = "application/json; charset=utf-8")
@ResponseBody
public ResponseBean insert(DemoDTO demoDTO) {
log.info("demo--------insert------請求參數:{}", demoDTO);
return ResponseBean.buildSuccess(demoEntityService.insert(demoDTO));
}
@ApiOperation(notes = "findById",
value = "findById",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
response = UserDTO.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "demo主鍵", required = true, paramType = "path", dataType = "long"),
})
@GetMapping("findById/{id}")
@ResponseBody
public ResponseBean findById(@PathVariable Long id) {
log.info("demo--------findById------id:{}", id);
return ResponseBean.buildSuccess(demoEntityService.findById(id));
}
@ApiOperation(notes = "list",
value = "list",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
response = UserDTO.class)
@GetMapping("list")
@ResponseBody
public ResponseBean list() {
log.info("demo--------list------");
return ResponseBean.buildSuccess(demoEntityService.list());
}
@ApiOperation(notes = "dbTransactional",
value = "dbTransactional",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
response = UserDTO.class)
@PostMapping("dbTransactional")
@ResponseBody
public ResponseBean dbTransactional(UserDTO userDTO, CompanyDTO companyDTO) {
log.info("demo--------dbTransactional------");
demoEntityService.dbTransactional(userDTO, companyDTO);
return ResponseBean.buildSuccess("執行成功");
}
}
1.5、開始測試
1.5.1、UserController
測試
1.5.1、插入數據: /hlj/user/insert
1.5.1.1、測試數據
name | city |
---|---|
HealerJean | 北京 |
XiaoMing | 山西 |
1.5.1.2、查詢數據庫ds_0
中user
表的數據
select * from ds_0.user
id | city | name | status | create_time | update_time |
---|---|---|---|---|---|
1244541509103194113 | 北京 | HealerJean | 10 | 2020-03-30 16:26:33 | 2020-03-30 16:26:33 |
1244541907067146241 | 山西 | XiaoMing | 10 | 2020-03-30 16:28:07 | 2020-03-30 16:28:07 |
1.5.2、CompanyController
測試
1.5.1、插入數據: /hlj/company/insert
1.5.1.1、測試數據
name | companyNameEnglish |
---|---|
字節跳動 | zijie |
小米 | xiaomi |
1.5.1.2、查詢數據庫ds_1
中company
表的數據
select * from ds_1.company;
id | name | company_name_english | status | create_time | update_time |
---|---|---|---|---|---|
1244543048496648194 | 字節跳動 | zijie | 10 | 2020-03-30 16:32:39 | 2020-03-30 16:32:39 |
1244543217464184833 | 小米 | 小米 | 10 | 2020-03-30 16:33:20 | 2020-03-30 16:33:20 |
1.5.3、歸納總結
通過上面的兩個插入就可以看出來,縱向分庫實現了
問題
1、如果不指定默認數據源,有其他表存在的情況會使用哪個數據源呢?
1.1、DemoController
測試
1.1.1、插入數據:/hlj/demo/insert
1.1.2、查詢數據:/hlj/demo/findById
1.2、歸納總結
**查詢的時候:會隨機指定一個,如果對應數據庫表不存在,會報錯(如下), **
Caused by: java.sql.SQLSyntaxErrorException: Table 'ds_1.demo_entity' doesn't exist
插入的時候,會報錯,提示沒有數據源(如下)
### Error updating database. Cause: java.lang.IllegalStateException: Missing the data source name: 'null'
### The error may exist in com/healerjean/proj/dao/mapper/DemoEntityMapper.java (best guess)
### The error may involve com.healerjean.proj.dao.mapper.DemoEntityMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO demo_entity ( id, name, phone, status ) VALUES ( ?, ?, ?, ? )
### Cause: java.lang.IllegalStateException: Missing the data source name: 'null'
1.2、多個數據庫事務一致性
1.2.1、DemoController
測試
1.2.1.1、DemoEntityService
/**
* 測試多個數據庫事務
*/
void dbTransactional(UserDTO userDTO, CompanyDTO companyDTO);
1.2.1.2、DemoEntityServiceImpl
/**
* 分庫分表也是有事務的,如果跑出了異常,則都不能成功
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void dbTransactional(UserDTO userDTO, CompanyDTO companyDTO) {
userService.insert(userDTO);
companyService.insert(companyDTO);
int i = 1/0;
}
1.2.1.3、DemoController
@ApiOperation(notes = "dbTransactional",
value = "dbTransactional",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
response = UserDTO.class)
@PostMapping("dbTransactional")
@ResponseBody
public ResponseBean dbTransactional(UserDTO userDTO, CompanyDTO companyDTO) {
log.info("demo--------dbTransactional------");
demoEntityService.dbTransactional(userDTO, companyDTO);
return ResponseBean.buildSuccess("執行成功");
}
1.2.1.4、測試並總結
可以看到拋出了異常,兩個數據庫分表對應的表user、company中也有新添加的數據,說明事務是有一致性的
2020-03-30 16:49:00 ERROR -[ ]- ====系統錯誤=== java.lang.ArithmeticException: / by zero
at com.healerjean.proj.service.impl.DemoEntityServiceImpl.dbTransactional(DemoEntityServiceImpl.java:76) ~[classes/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_201]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_201]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_201]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_201]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.1.7.RELEASE.jar:5.1.7.RELEASE]