Spring基础篇:Spring操作数据库的方式以及事务控制(下)

115 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第18天,点击查看活动详情

在上篇中,我们发现当Service层操作Dao时,发生错误后会使Sql语句出现执行错误问题:用户A增加了100,用户B未执行减少操作

在该篇,我们将学习Spring的事务操作。(仅仅展示声明式事务)

Spring做事务管理的Bean

回顾:当我们自己手动操作事务的时候需要走这几步:

  1. 拿到DataSourceconnection
  2. 手动设置connectionsetAutoCommitfalse,我们需要自己编程控制事务的提交和回滚
  3. 使用try...catch将业务代码包围
  4. catch中设置回滚
  5. finally设置关闭connection

还挺麻烦的,现在框架的好处体现了,Spring帮我们做了这些事,我们只需要将一个Bean注入到容器中,管理我们的DataSource就行。

需要注入的Bean org.springframework.jdbc.datasource.DataSourceTransactionManager

注解篇

这里重点分享如何使用注解,编写声明式事务,因为注解相比其他方式真的太简单了。

编写配置文件

DataSourceTransactionManager注入到Spring容器中。在构造方法中只需要把driverManagerDataSource()通过依赖注入的方式注入。

@Configuration
@ComponentScan("juejin.jdbc.anno")
public class JdbcAnnotationConfig {
    @Bean
    public DriverManagerDataSource driverManagerDataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/juejin_sql");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(driverManagerDataSource());
    }
    
    // 这里是新内容
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(){
        return new DataSourceTransactionManager(driverManagerDataSource());
    }
}

添加@EnableTransactionManagement注解

@Configuration
@ComponentScan("juejin.jdbc.anno")
// 这里是新内容
@EnableTransactionManagement
public class JdbcAnnotationConfig 

在具体的业务上添加@Transactional注解

这里我们在业务AccountService上添加了@Transactional注解,表示该类中所有的方法都开启了事务。

@Service
@Transactional
public class AccountService {

    @Autowired
    AccountDao accountDao;
    // 一个交易方法
    public void deal(){
        accountDao.addMoney(1,100);
        int i = 1 / 0;
        accountDao.reduceMoney(2,100);
    }
}

测试

结果:数据库中的数据是正常的,表示SQL事务控制成功。

public class JdbcAnnotationApplication {
    public static void main(String[] args) throws SQLException {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JdbcAnnotationConfig.class);
        AccountService service = ctx.getBean(AccountService.class);
        service.deal();
    }
}