搜尋
首頁資料庫mysql教程MySQL Innodb事務程式設計問題與處理

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(&#39;a&#39;,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(&#39;a&#39;,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(&#39;a&#39;,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 &#39;0&#39;,
  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)!


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
將用戶添加到MySQL:完整的教程將用戶添加到MySQL:完整的教程May 12, 2025 am 12:14 AM

掌握添加MySQL用戶的方法對於數據庫管理員和開發者至關重要,因為它確保數據庫的安全性和訪問控制。 1)使用CREATEUSER命令創建新用戶,2)通過GRANT命令分配權限,3)使用FLUSHPRIVILEGES確保權限生效,4)定期審計和清理用戶賬戶以維護性能和安全。

掌握mySQL字符串數據類型:varchar vs.文本與char掌握mySQL字符串數據類型:varchar vs.文本與charMay 12, 2025 am 12:12 AM

chosecharforfixed-lengthdata,varcharforvariable-lengthdata,andtextforlargetextfield.1)chariseffity forconsistent-lengthdatalikecodes.2)varcharsuitsvariable-lengthdatalikenames,ballancingflexibilitibility andperformance.3)

MySQL:字符串數據類型和索引:最佳實踐MySQL:字符串數據類型和索引:最佳實踐May 12, 2025 am 12:11 AM

在MySQL中處理字符串數據類型和索引的最佳實踐包括:1)選擇合適的字符串類型,如CHAR用於固定長度,VARCHAR用於可變長度,TEXT用於大文本;2)謹慎索引,避免過度索引,針對常用查詢創建索引;3)使用前綴索引和全文索引優化長字符串搜索;4)定期監控和優化索引,保持索引小巧高效。通過這些方法,可以在讀取和寫入性能之間取得平衡,提升數據庫效率。

mysql:如何遠程添加用戶mysql:如何遠程添加用戶May 12, 2025 am 12:10 AM

ToaddauserremotelytoMySQL,followthesesteps:1)ConnecttoMySQLasroot,2)Createanewuserwithremoteaccess,3)Grantnecessaryprivileges,and4)Flushprivileges.BecautiousofsecurityrisksbylimitingprivilegesandaccesstospecificIPs,ensuringstrongpasswords,andmonitori

MySQL字符串數據類型的最終指南:有效的數據存儲MySQL字符串數據類型的最終指南:有效的數據存儲May 12, 2025 am 12:05 AM

tostorestringsefliceflicyInmySql,ChooSetherightDataTypeBasedyOrneOrneEds:1)USEcharforFixed-LengthStstringStringStringSlikeCountryCodes.2)UseVarcharforvariable-lengtthslikenames.3)USETEXTCONTENT.3)

mysql blob vs.文本:為大對象選擇正確的數據類型mysql blob vs.文本:為大對象選擇正確的數據類型May 11, 2025 am 12:13 AM

選擇MySQL的BLOB和TEXT數據類型時,BLOB適合存儲二進制數據,TEXT適合存儲文本數據。 1)BLOB適用於圖片、音頻等二進制數據,2)TEXT適用於文章、評論等文本數據,選擇時需考慮數據性質和性能優化。

MySQL:我應該將root用戶用於產品嗎?MySQL:我應該將root用戶用於產品嗎?May 11, 2025 am 12:11 AM

No,youshouldnotusetherootuserinMySQLforyourproduct.Instead,createspecificuserswithlimitedprivilegestoenhancesecurityandperformance:1)Createanewuserwithastrongpassword,2)Grantonlynecessarypermissionstothisuser,3)Regularlyreviewandupdateuserpermissions

MySQL字符串數據類型說明了:選擇適合您數據的合適類型MySQL字符串數據類型說明了:選擇適合您數據的合適類型May 11, 2025 am 12:10 AM

mySqlStringDatatAtatPessHouldBechoseBasedondatActarActeristicsAndusecases:1)USEcharforFixed lengthStstringStringStringSlikeCountryCodes.2)usevarcharforvariable-lengtthslikeLikenames.3)usebarnionororvarinyorvarinyorvarybinarydatalgebenedaTalgeextocrabextrapon.4)

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SecLists

SecLists

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

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具