MySQL的MyISAM模式导致事务回滚失效,将其改为InnoDB模式事务再次生效

8 篇文章 0 订阅

​公司的老系统是php开发的,而且是通过第三方授权的购买的,现在因为这种第三方的互联网产品在授权上很多都说得很模糊,让用户很多时候会踩坑,像有的刚开始说免费使用的,然而当你放心使用的时候突然接到律师函说侵权了……

吃过这种亏后,老板为了规避这种风险,决定重构一套,但是原先的客户数据实在太多了,所以打算基于原先系统的库表用java来做一套,这样也省得迁移数据之类的问题了。

然而在做的过程中发现当需要同时进行多张表操作的时候,去进行事务回滚数据库却没有回滚数据,明明在service中的方法都加了**@Transactional**注解,而且我人为抛出非检异常 **int i=1/0;**按理不应该不回滚。

@Service
public class UsersService {

    @Autowired
    private TUserMapper tUserMapper;

    @Transactional
    public void deleteUser(Long uid) {
        tUserMapper.deleteByPrimaryKey(uid);
        int i = 1 / 0;
    }

    @Transactional
    public void insertUser() {
        TUser tUser = new TUser();
        tUser.setName("bruce");
        tUserMapper.insert(tUser);

        tUser = new TUser();
        tUser.setName("bill");
        tUserMapper.insert(tUser);

        int i = 1 / 0;
    }
}

​于是把工程中各种配置重新查了一遍,启动类配置类等等都查了一遍,把数据库挪到别的服务器上再试了几遍,还是不行。

@MapperScan("com.bruce.testmybatis.mapper")
@EnableTransactionManagement
@SpringBootApplication
public class TestMybatisApplication {
	public static void main(String[] args) {
		SpringApplication.run(TestMybatisApplication.class, args);
	}
}

后来干脆我新建一个Springboot+mybatisplus工程,再试了一遍,结果还是没有回滚数据。

想来想去可能不是代码的问题,会不会是数据库问题,毕竟一直在测试同一个数据库,即使到别的服务器上测试也是用的同步过去的数据库。于是我单独新建一个数据库,再跑几遍程序,结果所有的事务都正常执行……

被折磨了一天,居然是数据库的问题,实在是

WTF

于是我查了下原因,原先系统的数据库是php的工程自动化创建的,但是它自动创建的数据库引擎是 MyISAM,而这种引擎模式性能极佳,唯一的问题就是不支持事务。现在开发的系统对事务的要求越来越高,所以不可能再用MyISAM引擎模式,应该将其改为InnoDB引擎模式,InnoDB因为加了事务等一系列的功能后,这些记录事务的操作会占用一定的系统资源,而对于原先的数据并不会有什么影响。相反如果要从InnoDB转为MyISAM的话,可能会有点问题,因为MyISAM还不支持外键等约束……所以将MyISAM改为InnoDB除了对系统资源有影响外对数据基本不会有什么影响。

在服务器资源充裕且对数据没什么影响的情况下,果断将MyISAM转为InnoDB。因为一个MySQL数据库是允许部分MyISAM模式,部分InnoDB模式的,所以应该对表进行操作设置,通过下面SQL语句,会生成所有MyISAM模式的表

SELECT CONCAT('ALTER TABLE ', table_schema, '.', table_name, ' ENGINE=InnoDB;')
   FROM information_schema.tables
   WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema', 'performance_schema', 'mysql'); -- 排除系统库

在这里插入图片描述

将生成的语句全选,复制到查询面板,因为它生成的语句包含了服务器上所有数据库中的MyISAM模式的表,而我需要改的是wxsm数据库中的表,所以需要在查询面板中先筛选一下。

当我筛选好后执行命令,就批量将对应的表的模式由MyISAM改为InnoDB了。

image-20240419141311496

这时候,再去执行service代码,所有的事务回滚全部生效。

开森

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值