業務系統提交了一個數據庫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,系統宕機了。此時,數據庫的數據不會改變,數據庫連接會被清除,數據庫事務也會被清除,也不會鎖定數據
