SpringBoot超详细讲解事务管理
什么是事务管理?
在数据库中,事务是一组要么全部执行、要么全部不执行的操作序列。如果在事务中任何一个操作失败,整个事务都应该失败并回滚到事务开始状态。
事务管理就是保证在数据库操作中,一组操作要么全部完成,要么全部不完成的机制。
Spring中的事务管理
Spring框架中提供了多种方式进行事务管理,包括声明式事务管理和编程式事务管理。
声明式事务管理
声明式事务管理是根据注解或者配置文件来配置事务,使得在进行数据库操作时自动开启、提交或者回滚事务。一般使用在Service层。
在SpringBoot中,需要在启动类上添加@EnableTransactionManagement
注解来启动声明式事务管理。
@SpringBootApplication
@EnableTransactionManagement
public class SpringBootDemoApplication {
// ...
}
注解方式
在方法上或类上使用注解的方式来配置事务:
@Transactional
:配置方法使用事务- 可以指定事务的传播行为、隔离级别、是否只读以及回滚条件等属性
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false, rollbackFor = Exception.class)
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public void transfer(String from, String to, Integer money) {
// TODO: transfer money from account `from` to account `to`
// ...
}
}
配置文件方式
在配置文件中配置事务的方式:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.example.service.*.*(..))" id="serviceMethods" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" />
</aop:config>
编程式事务管理
编程式事务管理是通过代码方式控制事务的开启、提交和回滚。一般使用在DAO层。
public interface UserDao {
void transfer(String from, String to, Integer money);
}
public class UserDaoImpl implements UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void transfer(String from, String to, Integer money) {
try {
// 开启事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
// TODO: transfer money from account `from` to account `to`
// ...
// 提交事务
TransactionAspectSupport.currentTransactionStatus().flush();
} catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
}
示例
声明式事务管理
假设有一个转账服务,需要转账金额并在数据库中记录转账日志。
@Service
public class AccountService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public void transfer(String from, String to, Integer money) {
jdbcTemplate.update("UPDATE account SET balance = balance - ? WHERE id = ?", money, from);
jdbcTemplate.update("INSERT INTO log (account_id, money) VALUES (?, ?)", from, money);
jdbcTemplate.update("UPDATE account SET balance = balance + ? WHERE id = ?", money, to);
jdbcTemplate.update("INSERT INTO log (account_id, money) VALUES (?, ?)", to, money);
}
}
编程式事务管理
以SpringBoot和Mybatis为例实现编程式事务管理。
@Service
public class AccountService {
@Autowired
private AccountDao accountDao;
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public void transfer(String from, String to, Integer money) {
accountDao.transfer(from, money * -1);
accountDao.transfer(to, money);
}
}
@Repository
public class AccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void transfer(String id, Integer money) {
try {
// 开启事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
jdbcTemplate.update("UPDATE account SET balance = balance + ? WHERE id = ?", money, id);
// 提交事务
TransactionAspectSupport.currentTransactionStatus().flush();
} catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
}
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot超详细讲解事务管理 - Python技术站