Spring @Transactional
Spring 中使用
-
使用注解
@EnableTransactionManagement开启事务 -
配置事务管理器
-
使用 @Transactional 注解标注某个方法就可以了
@Configuration
@EnableTransactionManagement // 启用声明式事务
public class AppConfig {
@Bean // 数据源
public DataSource dataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("root");
dataSource.setPassword("password");
dataSource.setMaximumPoolSize(10);
return dataSource;
}
@Bean // 事务管理器
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource());
}
}
SpringBoot 中使用
直接使用,不需要任何配置
默认的数据源和事务管理器都配置好了,也启用了声明式事务(@EnableTransactionManagement )
@Transactional 可以写在类上(表示所有方法上都加了),也可以单独方法上。如果类和方法上同时存在,方法上的更优先
@Transactional // 加上这个注解就好了
public void transfer(int fromId, int toId, int amount) {
// 扣钱
jdbcTemplate.update("UPDATE account SET balance = balance - ? WHERE id = ?", amount, fromId);
// 加钱
jdbcTemplate.update("UPDATE account SET balance = balance + ? WHERE id = ?", amount, toId);
}
配置属性
- isolation - 事务隔离级别
- propagation - 事务传播行为
- timeout - 事务超时时间(秒)
- readOnly - 是否只读事务(默认为false)
- rollbackFor/rollbackForClassName - 指定哪些异常触发回滚
- noRollbackFor/noRollbackForClassName - 指定哪些异常不触发回滚
隔离级别
DEFAULT: 使用数据库默认隔离级别READ_UNCOMMITTED: 读未提交READ_COMMITTED: 读已提交(如果要保证不发生脏读,用这个级别,Oracle、PG 默认)REPEATABLE_READ: 可重复读(如果要保证不发生不可重复读,用这个级别,Mysql 默认)SERIALIZABLE: 串行化(如果要保证不发生幻读,用这个级别)
传播行为
REQUIRED(默认): 如果当前存在事务,则加入该事务;如果不存在,则创建一个新事务(一个事务)REQUIRES_NEW: 创建一个新事务,如果当前存在事务,则挂起当前事务(两个事务)SUPPORTS: 如果当前存在事务,则加入该事务;如果不存在,则以非事务方式执行(最多一个事务)NOT_SUPPORTED: 以非事务方式执行,如果当前存在事务,则挂起当前事务(可能没有事务)MANDATORY: 必须在一个已有的事务中执行,否则抛出异常NEVER: 必须不在事务中执行,否则抛出异常NESTED: 如果当前存在事务,则在嵌套事务中执行(和加入事务、新开事务都不一样,这里是子事务)

浙公网安备 33010602011771号