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