一、复杂方案(手动开启/提交/回滚事务)
- 代码管理事务
- 事务管理工具类
package com.shkj.util.transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/**
* 事务管理
* @author Lambert
*/
@Component
public class TransactionUtil {
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
/**
* 开启事务
* @return
*/
public TransactionStatus begin(){
return beginTransaction(dataSourceTransactionManager);
}
/**
* 提交事务
* @param status
*/
public void commit(TransactionStatus status){
commitTransaction(dataSourceTransactionManager,status);
}
/**
* 回滚事务
* @param status
*/
public void rollback(TransactionStatus status){
rollbackTransaction(dataSourceTransactionManager,status);
}
/**
* 开启事务
*/
public TransactionStatus beginTransaction(DataSourceTransactionManager transactionManager){
DefaultTransactionDefinition def = new DefaultTransactionDefinition();//事务定义类
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);// 返回事务对象
return status;
}
/**
* 提交事务
* @param transactionManager
* @param status
*/
public void commitTransaction(DataSourceTransactionManager transactionManager,TransactionStatus status){
transactionManager.commit(status);
}
/**
* 事务回滚
* @param transactionManager
* @param status
*/
public void rollbackTransaction(DataSourceTransactionManager transactionManager,TransactionStatus status){
transactionManager.rollback(status);
}
}
- 事务操作
- mybatis
/**
* @author Lambert
*/
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
class DeviceTest {
@Autowired
private TransactionUtil transactionUtil;
@Autowired
private IAliFaceEntityService aliFaceEntityService;
@Test
void test() {
TransactionStatus status = null;
try {
// 开启事务
status = transactionUtil.begin();
AliFaceEntity aliFace = new AliFaceEntity();
aliFace.setDbName("dbName1");
aliFaceEntityService.insertAliFaceEntity(aliFace);
// int i = 12 / 0;
aliFace.setDbName("dbName2");
aliFaceEntityService.insertAliFaceEntity(aliFace);
// 提交事务
transactionUtil.commit(status);
} catch (Exception e) {
System.out.println(e.getMessage());
// 回滚事务
transactionUtil.rollback(status);
}
}
}
- JdbcTemplate
/**
* @author Lambert
*/
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
class DeviceTest {
@Autowired
private TransactionUtil transactionUtil;
@Autowired
private IAliFaceEntityService aliFaceEntityService;
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private RestTemplate restTemplate;
@Autowired
private RedisCache redisCache;
@Test
public AjaxResult home(HelpageConsumData helpageConsumData) {
// 余额
BigDecimal balance = null;
// 扣款
BigDecimal consumPrice = null;
// 查询余额是否满足扣款
BigDecimal balanceAccount = jdbcTemplate.queryForObject("",BigDecimal.class);
if (balanceAccount.compareTo(new BigDecimal(helpageConsumData.getConsumPrice())) < 0) {
return AjaxResult.error("余额为balanceAccount,不够此次扣款");
}
/**
* 若消费成功,插入服务记录
*/
TransactionStatus status = null;
try {
// 开启事务
status = transactionUtil.begin();
/**
* 扣款并更新余额
*/
consumPrice = new BigDecimal(helpageConsumData.getConsumPrice());
balance = balanceAccount.subtract(consumPrice);
int update = jdbcTemplate.update("");
/**
* 若扣款成功则更新消费记录状态
*/
if (update > 0) {
Date date = new Date();
jdbcTemplate.update("");
}
// int o = 1/0;
// 提交事务
transactionUtil.commit(status);
} catch (Exception e) {
// 回滚事务
transactionUtil.rollback(status);
return AjaxResult.error("扣款错误,请重新操作");
}
// 返回成功消息及扣款信息
return AjaxResult.success("success", null);
}
}
二、 简单方案(SpringBoot管理事务)
- Spring Boot 使用事务非常简单
- 首先使用注解 @EnableTransactionManagement 开启事务支持后,
- 然后在访问数据库的Service方法上添加注解 @Transactional 便可。
- 第一步 启动类配置
/**
* 启动程序
* @author Lambert
*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableTransactionManagement
public class RuoYiApplication {
public static void main(String[] args) {
// System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(RuoYiApplication.class, args);
System.out.println("启动成功");
}
}
- 第二步 service实现类
/**
* 阿里人脸样本 服务层实现
* @author Lambert
* @date 2022-02-07
*/
@Service
public class AliFaceEntityServiceImpl implements IAliFaceEntityService {
@Autowired
private AliFaceEntityMapper aliFaceEntityMapper;
/**
* 新增阿里人脸样本
*
* @param aliFaceEntity 阿里人脸样本信息
* @return 结果
*/
@Override
@Transactional
public int insertAliFaceEntity(AliFaceEntity aliFaceEntity) {
aliFaceEntityMapper.insertAliFaceEntity(aliFaceEntity);
int i = 12/0;
aliFaceEntity.setDbName("asd");
return aliFaceEntityMapper.insertAliFaceEntity(aliFaceEntity);
}
}
- 测试
/**
* @author Lambert
*/
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
class DeviceTest {
@Autowired
private TransactionUtil transactionUtil;
@Autowired
private IAliFaceEntityService aliFaceEntityService;
@Test
void test() {
AliFaceEntity aliFace = new AliFaceEntity();
aliFace.setDbName("1111");
aliFaceEntityService.insertAliFaceEntity(aliFace);
}
}
-
回滚成功
-
细节探究看此链接(待完善)