业务系统提交了一个数据库dml指令,在尚未进行提交时,系统宕机了。那么数据库的数据会是修改前的,还是修改后的?数据库中的连接是否会断开,数据是否会被锁定?带着这些疑问,我们做的如下测试:
1、在数据库中插入一条数据
此时,数据库中用户密码为:test
2、查看数据库的连接
show FULL PROCESSLIST;
此时存在一个连接,该连接时navicat的客户端连接
3、查看数据库的事务
SELECT * FROM information_schema.INNODB_TRX;
不存在事务
4、执行业务系统中的修改语句
@Transactional(rollbackFor = Exception.class) public void update(){ UserEntity userEntity = new UserEntity(); userEntity.setId(2); //修改数据库的用户密码为 test112 userEntity.setPassword("test112"); userMapper.updateById(userEntity); } @Transactional(rollbackFor = Exception.class) public void shutdown(){ update(); try { //模拟长事务,方便我们测试系统宕机 Thread.sleep(5000000); } catch (InterruptedException e) { e.printStackTrace(); } } @Test public void testShutDown(){ userService.shutdown(); }
执行testShutDown方法
5、再次查看数据库的连接
多了很多连接,这是因为我在代码中使用了数据库连接池,默认创建了5个连接
6、再次查看数据库的事务
此时有一个正在运行中的事务,且锁住了一行
7、我们直接kill掉业务系统的进程
taskkill /f /pid 13964
8、查看数据库连接
数据库连接已经关闭
9、查看数据库事务
事务已经没有了
10、查看数据
数据未改变
--------------------------------------------
以上测试在windows 10机器上进行测试的,mysql版本5.7.30 社区版,使用了druid连接池
在centos 7.5上,其他条件不变,得到和上面一致结果
在windows10上,使用jdbc连接,不使用连接池,其他条件不变,得到和上面有一致结果
结论:当系统提交了数据库dml指令,但未执行commit,系统宕机了。此时,数据库的数据不会改变,数据库连接会被清除,数据库事务也会被清除,也不会锁定数据