闽公网安备 35020302035485号
作为后端开发的程序员,我们常常会的一些相对比较复杂的逻辑,比如我们需要给前端写一个调用的接口,这个接口需要进行相对比较复杂的业务逻辑操作,比如会进行,查询、远程接口或本地接口调用、更新、插入、计算等一些逻辑,将最终接口的返回结果给到前端,而经过这么一系列的业务逻辑操作,接口对DB的操作、对代码业务逻辑判断、进行接口调用这些都是需要时间的,而只要这是一个事务操作,每次对数据库进行的交互都会产生一条事务记录。
那么这样就会对我们接口返回的效率产生影响,而且这个影响是随着数据量的增长而增长的,这时候我们就需要对一整个大事务进行拆分,从而提升整体接口的效率。

首先事务里面进行远程的接口调用,如果不采用分布式事务框架,本身就会存在事务不一致的情况,无法进行数据的回滚操作,并发情况下远程服务响应不及时,会出现接口返回不一致问题,当然必须采用异步调用,后面会提到。
public Boolean transactionCommit(String userName) {
//查询用户
SysUser sysUser = userMapper.selectUserByUserName(userName,null);
// 堆代码 duidaima.com
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
try {
if (null != sysUser) {
//用户信息状态更新 status更新为1
userMapper.updateStatus(userName);
}
} catch (Exception e){
//回滚
transactionStatus.setRollbackOnly();
}
}
});
//再次查询
SysUser sysUser1 = userMapper.selectUserByUserName(userName,"1");
/log/.info("状态为1的用户信息"+JSON./toJSONString/(sysUser1));
return true;
}
编程式事务的灵活点在于可以控制事务执行方法,运用transactionTemplate类进行事务操作,查询操作可以写在外面,这样查询获取数据的操作就不会进入mysql事务表。List<List<ReceivableFeeSaveDTO>> partition = Lists.partition(receivableFeeSaveDTOList, 50);4.大事务拆分小事务
CompletableFuture<Object> task1 =CompletableFuture.supplyAsync(() -> {
System.out.println("单号check线程" + Thread.currentThread().getId());
//单号check接口 校验失败抛出异常
return "账单实体信息";
}, executor);
CompletableFuture<Object> task2 = CompletableFuture.supplyAsync(() -> {
System.out.println("收款单生成线程" + Thread.currentThread().getId());
try {
//收款单生成
return “账单编号”;
Thread.sleep(3000);
System.out.println("任务2结束:");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, executor);
//task1、task2 执行完执行task3 ,需要感知task1和task2的执行结果
CompletableFuture<Boolean> future = task1.thenCombineAsync(task2, (t1, t2) -> {
System.out.println("账单金额回写线程" + Thread.currentThread().getId());
// t1 、t2返回判断
//回写返回结果
return ture;
}, executor);
总结