1.在循環中提交的問題
很多開發人員非常喜歡在循環中進行事務提交,下面演示一個他們經常寫的一個存儲過程示例,如下所示:
DROP PROCEDURE IF EXISTS load1;CREATE PROCEDURE load1(count INT UNSIGNED)BEGIN DECLARE s INT UNSIGNED DEFAULT 1; DECLARE c CHAR(80) DEFAULT REPEAT('a',80); WHILE s <= count DO INSERT INTO t1 select NULL,c; COMMIT; SET s=s+1; END WHILE;END;
在上面的例子中,是否加上commit指令並不是關鍵。由於MySQL innodb的儲存引擎預設為自動提交,因此去掉預存程序中的commit結果是一樣的。如下圖所示,以下也是另一個容易被開發人員忽略的問題:
DROP PROCEDURE IF EXISTS load2; CREATE PROCEDURE load2(count INT UNSIGNED)BEGIN DECLARE s INT UNSIGNED DEFAULT 1; DECLARE c CHAR(80) DEFAULT REPEAT('a',80); WHILE s <= count DO INSERT INTO t1 select NULL,c; SET s=s+1; END WHILE;END;
不論上面哪個預存過程,當發生錯誤時,資料庫會停留在一個未知的位置。例如我們要插入10000條數據,但是在插入5000條時發生了錯誤,然而這5000條已經存放在了數據庫中,我們如何處理?另外一個是效能問題,上面的兩個預存程序都不會比下面的這個預存程序快,因為下面這個是將insert放在了一個事務中:
DROP PROCEDURE IF EXISTS load3; CREATE PROCEDURE load3(count INT UNSIGNED)BEGIN DECLARE s INT UNSIGNED DEFAULT 1; DECLARE c CHAR(80) DEFAULT REPEAT('a',80); START TRANSACTION; WHILE s <= count DO INSERT INTO t1 select NULL,c; SET s=s+1; END WHILE; COMMIT;END;
對於上面三個預存過程,我們分別插入100萬數據來比較執行時間,如下所示,顯然可以看到第三種方法快很多,這是因為每次提及都要寫一次重做日誌,所以load1和load2實際寫了100萬次重做紀錄.對於預存程序load3,我們只寫了1次重做日誌。
先準備一個測試表
CREATE TABLE `t1` (`id` int NOT NULL AUTO_INCREMENT ,`name` varchar(500) NULL , PRIMARY KEY (`id`) ) ;
執行測試
09:50:44 test> call load1(1000000); Query OK, 0 rows affected (1 min 4.90 sec)09:54:23 test> truncate table t1; Query OK, 0 rows affected (0.05 sec)09:54:25 test> call load2(1000000); Query OK, 1 row affected (1 min 3.38 sec)09:55:32 test> truncate table t1; Query OK, 0 rows affected (0.20 sec)09:55:58 test> call load3(1000000); Query OK, 0 rows affected (33.90 sec)
對於第二個預存程序load2,我們也可以人為的開啟下事務,同樣可以達到存儲過程load3的效果,執行時間如下所示:
09:57:42 test> begin; Query OK, 0 rows affected (0.00 sec)09:57:46 test> call load2(1000000); Query OK, 1 row affected (34.08 sec)09:58:26 test> commit; Query OK, 0 rows affected (0.76 sec)
2.關於使用自動提交
在一些特殊場景下,有時候自動提交不一定是個好的事情, 如我們上面講到的循環提交的問題,MySQL資料庫預設是自動提交(autocommit)。可以透過以下方式來改變MySQL的提交方式:
10:35:34 test> SET AUTOCOMMIT=0; Query OK, 0 rows affected (0.00 sec)
也可以使用START TRANSATION或BEGIN顯示的開啟一個事務。 MySQL會自動執行
SET AUTOCOMMIT=0,並在COMMIT或ROLLBACK結束一個事務後執行SET AUTOCOMMIT=1 。
3.使用自動回滾處理異常 當儲存過程發生異常的時候怎麼辦,Innodb儲存引擎支援透過一個HANDLER來進行交易的自動回滾操作。如在預存程序中發生錯誤會自動進行回滾操作。如下面一個範例:
CREATE PROCEDURE sp_auto_rollback_demo()BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; START TRANSACTION; INSERT INTO b select 1; INSERT INTO b select 2; INSERT INTO b select 1; INSERT INTO b select 3; COMMIT;END;
測試表如下
CREATE TABLE `b` ( `a` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
執行上面的預存程序,因此會在插入第二個記錄1時發生錯誤,但是因為啟用了自動回滾操作,這個預存程序執行結果如下:
10:09:46 test> call sp_auto_rollback_demo; Query OK, 0 rows affected (0.01 sec)10:10:04 test> select * from b;Empty set (0.00 sec)
看起來沒有問題,運作比較正常,但是在執行sp_auto_rollback_demo的時候是執行成功了還是失敗了?對此,我們可以進行如下處理,示例如下:
DROP PROCEDURE IF EXISTS sp_auto_rollback_demo;CREATE PROCEDURE sp_auto_rollback_demo()BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT -1; END; START TRANSACTION; INSERT INTO b select 1; INSERT INTO b select 2; INSERT INTO b select 1; INSERT INTO b select 3; COMMIT; SELECT 1;END;
當發生錯誤時,先回滾然後返回-1,表示運行發生了錯誤。返回1表示運作正常。運行結果如下:
10:16:19 test> call sp_auto_rollback_demo\G*************************** 1. row ***************************-1: -1 1 row in set (0.00 sec) Query OK, 0 rows affected (0.01 sec) 10:16:35 test> select * from b; Empty set (0.00 sec)
以上就是MySQL Innodb事務程式設計問題與處理的內容,更多相關內容請關注PHP中文網(www.php.cn)!

在數據庫優化中,應根據查詢需求選擇索引策略:1.當查詢涉及多個列且條件順序固定時,使用複合索引;2.當查詢涉及多個列但條件順序不固定時,使用多個單列索引。複合索引適用於優化多列查詢,單列索引則適合單列查詢。

要優化MySQL慢查詢,需使用slowquerylog和performance_schema:1.啟用slowquerylog並設置閾值,記錄慢查詢;2.利用performance_schema分析查詢執行細節,找出性能瓶頸並優化。

MySQL和SQL是開發者必備技能。 1.MySQL是開源的關係型數據庫管理系統,SQL是用於管理和操作數據庫的標準語言。 2.MySQL通過高效的數據存儲和檢索功能支持多種存儲引擎,SQL通過簡單語句完成複雜數據操作。 3.使用示例包括基本查詢和高級查詢,如按條件過濾和排序。 4.常見錯誤包括語法錯誤和性能問題,可通過檢查SQL語句和使用EXPLAIN命令優化。 5.性能優化技巧包括使用索引、避免全表掃描、優化JOIN操作和提升代碼可讀性。

MySQL異步主從復制通過binlog實現數據同步,提升讀性能和高可用性。 1)主服務器記錄變更到binlog;2)從服務器通過I/O線程讀取binlog;3)從服務器的SQL線程應用binlog同步數據。

MySQL是一個開源的關係型數據庫管理系統。 1)創建數據庫和表:使用CREATEDATABASE和CREATETABLE命令。 2)基本操作:INSERT、UPDATE、DELETE和SELECT。 3)高級操作:JOIN、子查詢和事務處理。 4)調試技巧:檢查語法、數據類型和權限。 5)優化建議:使用索引、避免SELECT*和使用事務。

MySQL的安裝和基本操作包括:1.下載並安裝MySQL,設置根用戶密碼;2.使用SQL命令創建數據庫和表,如CREATEDATABASE和CREATETABLE;3.執行CRUD操作,使用INSERT,SELECT,UPDATE,DELETE命令;4.創建索引和存儲過程以優化性能和實現複雜邏輯。通過這些步驟,你可以從零開始構建和管理MySQL數據庫。

InnoDBBufferPool通過將數據和索引頁加載到內存中來提升MySQL數據庫的性能。 1)數據頁加載到BufferPool中,減少磁盤I/O。 2)臟頁被標記並定期刷新到磁盤。 3)LRU算法管理數據頁淘汰。 4)預讀機制提前加載可能需要的數據頁。

MySQL適合初學者使用,因為它安裝簡單、功能強大且易於管理數據。 1.安裝和配置簡單,適用於多種操作系統。 2.支持基本操作如創建數據庫和表、插入、查詢、更新和刪除數據。 3.提供高級功能如JOIN操作和子查詢。 4.可以通過索引、查詢優化和分錶分區來提升性能。 5.支持備份、恢復和安全措施,確保數據的安全和一致性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

WebStorm Mac版
好用的JavaScript開發工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

Atom編輯器mac版下載
最受歡迎的的開源編輯器