Spring + Mybatis + MySQL 使用事物的几种方法总结
在 Spring + Mybatis + MySQL 项目中,我们经常需要使用事务来保证多个操作的一致性,或者保证某些操作的原子性。本文将总结一些使用事务的常用方法。
1. 声明式事务
1.1 基于注解的事务管理
1.1.1 配置数据源
首先需要在 Spring 的配置文件中配置数据源。
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
1.1.2 配置事务管理器
然后配置事务管理器。
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
1.1.3 配置事务注解驱动
最后配置事务注解驱动。
<tx:annotation-driven transaction-manager="transactionManager"/>
1.1.4 编写事务方法
接下来我们可以在 Service 层的方法中添加 @Transactional 注解来声明事务。
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Transactional
@Override
public void addUser(User user) {
userDao.addUser(user);
}
}
在该方法内部执行的所有操作都将受到事务管理。
1.2 基于 XML 配置的事务管理
1.2.1 配置数据源和事务管理器
在 Spring 的配置文件中配置数据源和事务管理器。
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
1.2.2 编写事务配置
在 Mybatis 的配置文件中配置事务。
<transactionManager type="SPRING">
<property name="dataSource" ref="dataSource"/>
</transactionManager>
1.3 事务传播行为
Spring 支持多种事务传播行为,以满足不同场景的需求。例如:
- REQUIRED:默认值,如果当前没有事务,就新建一个事务;如果已经存在一个事务中,加入这个事务,成为一个整体。
- SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
- MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。
- REQUIRES_NEW:新建一个全新的事务,如果当前存在事务,就把当前事务挂起。
- NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
- NESTED:在当前事务内开启一个新的嵌套事务,如果当前没有事务,就新建一个事务;如果已经存在一个事务中,就成为该事务的一个嵌套事务。
在嵌套事务中,内部事务的提交和回滚操作不会对外部事务产生影响。如果内部事务回滚,外部事务也可以回滚;但如果内部事务回滚以外的原因导致回滚,外部事务不会回滚。
2. 编程式事务
在 Spring 中可以通过编写代码来实现事务。可以使用 TransactionTemplate 或者 PlatformTransactionManager 来编程式处理事务。
2.1 TransactionTemplate
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Autowired
private TransactionTemplate transactionTemplate;
@Override
public void addUsers(List<User> users) {
transactionTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus transactionStatus) {
try {
for (User user : users) {
userDao.addUser(user);
}
} catch (Exception e) {
transactionStatus.setRollbackOnly();
return null;
}
return null;
}
});
}
}
2.2 PlatformTransactionManager
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Autowired
private PlatformTransactionManager transactionManager;
@Override
public void addUsers(List<User> users) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
for (User user : users) {
userDao.addUser(user);
}
transactionManager.commit(status); // 提交事务
} catch (Exception e) {
transactionManager.rollback(status); // 回滚事务
}
}
}
3. 示例
3.1 Spring + Mybatis + MySQL 声明式事务示例
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderDao orderDao;
@Transactional
@Override
public void addOrder(Order order) {
orderDao.addOrder(order); // 添加订单
orderDao.updateStock(order.getProductId(), order.getQuantity()); // 更新商品库存
}
}
3.2 Spring + Mybatis + MySQL 编程式事务示例
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderDao orderDao;
@Autowired
private PlatformTransactionManager transactionManager;
@Override
public void addOrder(Order order) {
TransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);
try {
orderDao.addOrder(order); // 添加订单
orderDao.updateStock(order.getProductId(), order.getQuantity()); // 更新商品库存
transactionManager.commit(status); // 提交事务
} catch (Exception e) {
transactionManager.rollback(status); // 回滚事务
}
}
}
以上就是 Spring + Mybatis + MySQL 使用事务的几种方法总结,希望能够对您有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring + mybatis + mysql使用事物的几种方法总结 - Python技术站