为什么少用@Transactional

我们知道@Transactional注解是通过spring的aop起作用的,但是如果使用不当,事务功能可能会失效。如果恰巧你经验不足,这种问题不太好排查。
@Transactional注解一般加在某个业务方法上,会导致整个业务方法都在同一个事务中,粒度太粗,不好控制事务范围,是出现大事务问题的最常见的原因。

手动编写事务代码如下:

	@Autowired
    private DimensionDao dimensionDao;
    
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    /**
     * 注意使用事务一定要是public的方法
     * @return  是否执行成功
     */
    @Override
    public boolean test() {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        // 定义该事务的名称、事务级别
        def.setName("txTest");
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        // 记录事务执行之前的状态
        TransactionStatus status = dataSourceTransactionManager.getTransaction(def);
        // 尽量要把select放到事务外面,因为查询不牵扯到事务
         dimensionDao.selectTest();
        // 此处设定的是sql语句出错,所以使用try catch包围,也可以根据实际的业务确定执行还是回滚
        try {
            // 执行操作 TODO
            dimensionDao.addTest01("name", "4");
            dimensionDao.addTest02("1", "dep_name");
            // 如果没有出错,提交该事务
            dataSourceTransactionManager.commit(status);
        } catch (Exception e) {
            // 错误输入改成日志
            System.err.println(e.getMessage());
            // 如果发送错误回滚该事物
            dataSourceTransactionManager.rollback(status);
            return false;
        }
        return true;
    }

当然,我说少使用@Transactional注解开启事务,并不是说一定不能用它,如果项目中有些业务逻辑比较简单,而且不经常变动,使用@Transactional注解开启事务开启事务也无妨,因为它更简单,开发效率更高,但是千万要小心事务失效的问题。

注意事项
1、少用@Transactional注解
2、将查询(select)方法放到事务外
3、事务中避免远程调用
4、事务中避免一次性处理太多数据
5、非事务执行
6、异步处理

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐