针对SpringBoot事务不回滚的问题,我们可以通过以下几个步骤来进行解决:
1.确认事务正常工作
首先,我们需要确认事务的确不会自动回滚。可以在事务中对一个数据库表进行操作,然后将该操作后面的代码注释掉,确保事务提交的同时没有任何异常抛出,这样可以验证事务框架是否生效。
2.添加事务管理器
如果事务确实没有通过Spring事务管理器自动回滚,那么需要手动进行添加。在SpringBoot项目中添加事务的步骤如下:
2.1 添加事务管理器依赖
在项目的pom.xml文件中添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
2.2 修改配置文件
在application.properties中添加以下配置信息:
#启用事务管理器
spring.datasource.platform=mysql
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123456
#开启事务的支持
spring.datasource.initialize=true
spring.datasource.continue-on-error=true
spring.datasource.rollback-on-commit-failure=true
spring.datasource.rollback-on-schema-error=true
#设置读写分离处理类
spring.datasource.initialize=true
spring.datasource.continue-on-error=true
spring.datasource.rollback-on-commit-failure=true
spring.datasource.rollback-on-schema-error=true
2.3 在代码中添加事务注解
在需要进行事务管理的方法上标注@Transactional
注解,例如:
@Transactional
public void saveOrUpdate(User user){
userDao.saveOrUpdate(user); //进行数据库写操作
//doSomething()不会影响到事务,即使doSomething发生了异常,事务也能够自动回滚
doSomething();
}
需要注意:@Transactional
注解需要添加在public方法上(或调用该方法的public方法)、或加在实现了接口的方法上。
3.示例说明
假设我们有一个User表,用于保存用户的信息。当用户进行登录操作时,需要进行用户信息查询和密码校验,此时我们希望该操作具有事务特性,即如果查询或校验失败,则不保存用户登录信息,需要回滚事务。
示例1:添加回滚事务注解
以下面的代码为例,我们需要在saveLoginInfo()
方法中添加@Transactional
注解,以实现事务回滚:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Transactional
public void saveLoginInfo(User user){
// 查询该用户信息
User queryUser = userDao.getUserByName(user.getName());
// 如果查询结果为空或者密码不匹配
if(queryUser == null || !queryUser.getPassword().equals(user.getPassword())){
throw new IllegalArgumentException("用户名或密码错误!");
}
// 校验通过则保存用户信息
userDao.saveOrUpdate(user);
}
// ...
}
在以上代码中,如果查询用户信息或者密码校验失败,则会抛出IllegalArgumentException异常,此时事务会自动回滚,不会保存用户登录信息。
示例2:手动回滚事务
还可以通过手动回滚事务的方式,来实现事务回滚的功能。例如:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Autowired
private PlatformTransactionManager transactionManager;
public void saveLoginInfo(User user){
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);
try {
// 查询该用户信息
User queryUser = userDao.getUserByName(user.getName());
// 如果查询结果为空或者密码不匹配
if(queryUser == null || !queryUser.getPassword().equals(user.getPassword())){
throw new IllegalArgumentException("用户名或密码错误!");
}
// 校验通过则保存用户信息
userDao.saveOrUpdate(user);
transactionManager.commit(status);
} catch (IllegalArgumentException e) {
transactionManager.rollback(status);
}
}
// ...
}
在以上代码中,我们首先使用PlatformTransactionManager
获取到事务对象,然后在需要回滚的地方手动调用transactionManager.rollback(status)
进行事务回滚,实现了事务的控制。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot事务不回滚的解决方案 - Python技术站