事务
事务就是为了保证多次数据库操作的原子性。举个简单的例子
买商品第一步要扣钱,第二步要扣库存。如果没有事务,一旦第一步与第二步之间出现了异常,那么钱是扣了,库存却没变,这显然不符合业务场景。要么都成功要嘛都失败
开启事务,在Springboot的启动类,或者某个@Configuration的类上加上@EnableTransactionManagement开启事务。因为这是数据库相关,所以我加在了Service的实现类上
首先导入pom文件依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <optional>true</optional>
</dependency>
<!-- mysql-connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
</dependencies>
springboot启动类
package com.lps;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
@SpringBootApplication
@EnableScheduling//开启定时任务
@MapperScan("com.lps.mapper")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Scheduled(fixedRate = 50 * 1000)//设置需要定时执行的任务 每50秒执行一次
public void doSomething() {
System.out.println("现在是" + System.currentTimeMillis());
}
}
实体类
@Data
public class Account {
private Integer id;
private String name;
private BigDecimal money;
}
yml文件配置
![](https://img-blog.csdnimg.cn/img_convert/41159f5eec31c0d5546eb9b5fad933fe.png)
Mapper文件
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lps.entity.Account;
import org.springframework.stereotype.Repository;
/**
* @author 阿水
* @create 2023-03-09 14:37
*/
@Repository
public interface AccountMapper extends BaseMapper<Account> {
}
Service接口
import java.math.BigDecimal;
/**
* @author 阿水
* @create 2023-03-09 14:37
*/
public interface AccountService {
/**
* 转账
* @param source 原账户
* @param target 目标账户
* @param money 转账金额
* @return
*/
boolean transfer(String source, String target, BigDecimal money);
}
Service实现类
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lps.entity.Account;
import com.lps.mapper.AccountMapper;
import com.lps.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
/**
* @author 阿水
* @create 2023-03-09 14:40
*/
@Service
@Transactional
public class AccountServiceImpl implements AccountService {
@Autowired(required = false)
private AccountMapper accountMapper;
@Override
public boolean transfer(String source, String target, BigDecimal money) {
boolean result = false;
//获取源账户
QueryWrapper<Account> wrapper1 = new QueryWrapper<>();
wrapper1.eq("name",source);
Account sourcePerson = accountMapper.selectOne(wrapper1);
//获取目标账户
QueryWrapper<Account> wrapper2 = new QueryWrapper<>();
wrapper2.eq("name",target);
Account targetPerson = accountMapper.selectOne(wrapper2);
//转账
//原账户取出700元
sourcePerson.setMoney(sourcePerson.getMoney().subtract(money));//进行十进制的减法
int a=accountMapper.updateById(sourcePerson);
//模拟异常
int x=10/0;
//目标账户存入700元
targetPerson.setMoney(targetPerson.getMoney().add(money));//进行十进制的加法
int b=accountMapper.updateById(targetPerson);
if (a>0 && b>0){
result=true;
}
return result;
}
}
Controller类
import com.lps.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
/**
* @author 阿水
* @create 2023-03-09 14:55
*/
@RestController
@CrossOrigin(origins = "*")
public class AccountController {
@Autowired
private AccountService accountService;
@GetMapping("/test")
public String test() {
boolean b=accountService.transfer("A","B", BigDecimal.valueOf(502));
return b?"转账成功":"转账失败";
}
}