共計 6036 個字符,預計需要花費 16 分鐘才能閱讀完成。
自動寫代碼機器人,免費開通
如何在 mysql 中事務處理?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
事務的特性:
事務有以下四個標準屬性的縮寫 ACID,通常被稱為:
原子性: 確保工作單元內的所有操作都成功完成,否則事務將被中止在故障點,和以前的操作將回滾到以前的狀態。
一致性: 確保數據庫正確地改變狀態后,成功提交的事務。
隔離性: 使事務操作彼此獨立的和透明的。
持久性: 確保提交的事務的結果或效果的系統出現故障的情況下仍然存在。
在 MySQL 中,事務開始使用 COMMIT
或ROLLBACK
語句開始工作和結束。開始和結束語句的 SQL 命令之間形成了大量的事務。
COMMIT
ROLLBACK
:
這兩個關鍵字提交和回滾主要用于 MySQL 的事務。
當一個成功的事務完成后,發出 COMMIT
命令應使所有參與表的更改才會生效。
如果發生故障時,應發出一個 ROLLBACK
命令返回的事務中引用的每一個表到以前的狀態。
可以控制的事務行為稱為 AUTOCOMMIT
設置會話變量。如果 AUTOCOMMIT
設置為 1(默認值),然后每一個 SQL 語句(在事務與否)被認為是一個完整的事務,并承諾在默認情況下,當它完成。AUTOCOMMIT
設置為 0 時,發出 SET AUTOCOMMIT
= 0 命令,在隨后的一系列語句的作用就像一個事務,直到一個明確的 COMMIT
語句時,沒有活動的提交。
可以通過使用 mysql_query()函數在 PHP 中執行這些 SQL 命令。
通用事務例子
這一系列事件是獨立于所使用的編程語言,可以建立在任何使用的語言來創建應用程序的邏輯路徑。
可以通過使用 mysql_query()函數在 PHP 中執行這些 SQL 命令。
BEGIN WORK 開始事務發出 SQL 命令
發出一個或多個 SQL 命令,如 SELECT,INSERT,UPDATE 或 DELETE
檢查是否有任何錯誤,一切都依據的需要。
如果有任何錯誤,那么問題 ROLLBACK
命令,否則發出 COMMIT
命令。
在 MySQL 中的事務安全表類型:
如果打算使用 MySQL 事務編程,那么就需要一種特殊的方式創建表。有很多支持事務但最流行的是 InnoDB 表類型。
從源代碼編譯 MySQL 時,InnoDB 表支持需要特定的編譯參數。如果 MySQL 版本沒有 InnoDB 支持,請互聯網服務提供商建立一個版本的 MySQL 支持 InnoDB 表類型,或者下載并安裝 Windows 或 Linux/UNIX 的 MySQL-Max 二進制分發和使用的表類型在開發環境中。
如果 MySQL 安裝支持 InnoDB 表,只需添加一個的 TYPE=InnoDB 定義表創建語句。例如,下面的代碼創建 InnoDB 表 tcount_tbl:
root@host# mysql -u root -p password;
Enter password:*******
mysql use TUTORIALS;
Database changed
mysql create table tcount_tbl
- ( - tutorial_author varchar(40) NOT NULL,
- tutorial_count INT
- ) TYPE=InnoDB;
Query OK, 0 rows affected (0.05 sec)
可以使用其他 GEMINI 或 BDB 表類型,但它取決于您的安裝,如果它支持這兩種類型。
由于項目設計里面,牽扯到了金錢的轉移,于是就要用到 MYSQL 的事務處理,來保證一組處理結果的正確性。用了事務,就不可避免的要犧牲一部分速度,來保證數據的正確性。
只有 InnoDB 支持事務
事務 ACID Atomicity(原子性)、Consistency(穩定性)、Isolation(隔離性)、Durability(可靠性)
1、事務的原子性
一組事務,要么成功;要么撤回。
2、穩定性
有非法數據(外鍵約束之類),事務撤回。
3、隔離性
事務獨立運行。
一個事務處理后的結果,影響了其他事務,那么其他事務會撤回。
事務的 100% 隔離,需要犧牲速度。
4、可靠性
軟、硬件崩潰后,InnoDB 數據表驅動會利用日志文件重構修改。
可靠性和高速度不可兼得,innodb_flush_log_at_trx_commit 選項 決定什么時候吧事務保存到日志里。
開啟事務
START TRANSACTION 或 BEGIN
提交事務(關閉事務)
COMMIT
放棄事務(關閉事務)
ROLLBACK
折返點
SAVEPOINT adqoo_1
ROLLBACK
TO SAVEPOINT adqoo_1
發生在折返點 adqoo_1 之前的事務被提交,之后的被忽略
事務的終止
設置“自動提交”模式
SET AUTOCOMMIT
= 0
每條 SQL 都是同一個事務的不同命令,之間由 COMMIT
或 ROLLBACK
隔開
掉線后,沒有 COMMIT
的事務都被放棄
事務鎖定模式
系統默認:不需要等待某事務結束,可直接查詢到結果,但不能再進行修改、刪除。
缺點:查詢到的結果,可能是已經過期的。
優點:不需要等待某事務結束,可直接查詢到結果。
需要用以下模式來設定鎖定模式
1、SELECT …… LOCK IN SHARE MODE(共享鎖)
查詢到的數據,就是數據庫在這一時刻的數據(其他已 commit 事務的結果,已經反應到這里了)
SELECT 必須等待,某個事務結束后才能執行
2、SELECT …… FOR UPDATE(排它鎖)
例如 SELECT * FROM tablename WHERE id 200
那么 id 200 的數據,被查詢到的數據,都將不能再進行修改、刪除、SELECT …… LOCK IN SHARE MODE 操作
一直到此事務結束
共享鎖 和 排它鎖 的區別:在于是否阻斷其他客戶發出的 SELECT …… LOCK IN SHARE MODE 命令
3、INSERT / UPDATE / DELETE
所有關聯數據都會被鎖定,加上排它鎖
4、防插入鎖
例如 SELECT * FROM tablename WHERE id 200
那么 id 200 的記錄無法被插入
5、死鎖
自動識別死鎖
先進來的進程被執行,后來的進程收到出錯消息,并按 ROLLBACK
方式回滾
innodb_lock_wait_timeout = n 來設置最長等待時間,默認是 50 秒
事務隔離模式
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL
READ UNCOMMIT
TED | READ COMMIT
TED | REPEATABLE READ | SERIALIZABLE
1、不帶 SESSION、GLOBAL 的 SET 命令
只對下一個事務有效
2、SET SESSION
為當前會話設置隔離模式
3、SET GLOBAL
為以后新建的所有 MYSQL 連接設置隔離模式(當前連接不包括在內)
隔離模式
READ UNCOMMIT
TED
不隔離 SELECT
其他事務未完成的修改(未 COMMIT
),其結果也考慮在內
READ COMMIT
TED
把其他事務的 COMMIT
修改考慮在內
同一個事務中,同一 SELECT 可能返回不同結果
REPEATABLE READ(默認)
不把其他事務的修改考慮在內,無論其他事務是否用 COMMIT
命令提交過
同一個事務中,同一 SELECT 返回同一結果(前提是本事務,不修改)
SERIALIZABLE
和 REPEATABLE READ 類似,給所有的 SELECT 都加上了 共享鎖
出錯處理
根據出錯信息,執行相應的處理
mysql 事物處理實例
MYSQL 的事務處理主要有兩種方法
1. 用 begin,rollback,commit 來實現
begin 開始一個事務
rollback 事務回滾
commit 事務確認
2. 直接用 set 來改變 mysql 的自動提交模式
mysql 默認是自動提交的,也就是你提交一個 query,就直接執行!可以通過
set autocommit = 0 禁止自動提交
set autocommit = 1 開啟自動提交
來實現事務的處理。
但要注意當用 set autocommit = 0 的時候,你以后所有的 sql 都將作為事務處理,直到你用 commit 確認或 rollback 結束,注意當你結束這個事務的同時也開啟了新的事務!按第一種方法只將當前的做為一個事務!
MYSQL 只有 INNODB 和 BDB 類型的數據表才支持事務處理,其他的類型是不支持的!
mysql use test;
Database changed
mysql CREATE TABLE `dbtest`( - id int(4)
- ) TYPE=INNODB;
Query OK, 0 rows affected, 1 warning (0.05 sec)
mysql select * from dbtest
- ;
Empty set (0.01 sec)
mysql begin;
Query OK, 0 rows affected (0.00 sec)
mysql insert into dbtest values(5);
Query OK, 1 row affected (0.00 sec)
mysql insert into dbtest value(6);
Query OK, 1 row affected (0.00 sec)
mysql commit;
Query OK, 0 rows affected (0.00 sec)
mysql select * from dbtest;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
mysql begin;
Query OK, 0 rows affected (0.00 sec)
mysql insert into dbtest values(7);
Query OK, 1 row affected (0.00 sec)
mysql rollback;
Query OK, 0 rows affected (0.00 sec)
mysql select * from dbtest;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
mysql 事務處理
php 代碼實現事務的處理可以通過 PHP 預定義類 mysqli 的以下方法實現。
autocommit(boolean):該方法用于限定查詢結果是否自動提交,如果該方法的參數為 true 則自動提交,如果參數為 false 則關閉自動提交。MySQL 數據庫默認為自動提交。
rollback():利用 mysqli 類中的該方法可以實現事務的回滾。
commit():利用該方法可以實現提交所有查詢。
?php
include_once( conn.php
$id=$_GET[id];
$conn- autocommit(false);
if(!$conn- query( delete from tb_sco where id= .$id.))
$conn- rollback();
if(!$conn- query( delete from tb_stu where id= .$id.))
$conn- rollback();
$conn- commit();
$conn- autocommit(true);
echo ok
?
?php require( connectDB.php // 建立數據庫連接 mssql_query( BEGIN TRANSACTION DEPS02_DEL // 開始事務 $delete_dep_sql= DELETE FROM TBLDEPARTMENT WHERE DEPTID= {$_GET[deptid]} // echo $delete_dep_sql. br mssql_query($delete_dep_sql); // 操作數據庫 // var_dump($del_result); $delete_result = mssql_query( select @@ROWCOUNT as id $delete_info = mssql_fetch_array($delete_result); $delete_rows = $delete_info[0]; // var_dump($delete_rows); mssql_free_result($delete_result); echo script language=javascript if(true){ // 判斷是否回滾提交 mssql_query(COMMIT
TRANSACTION DEPS02_DEL // 提交事務 echo alert(delete success!}else{mssql_query(ROLLBACK
TRANSACTION DEPS02_DEL // 回滾事務 echo alert( delete faile! echo /script mssql_close(); ?
MySQL 的事務處理在處理實際問題中有著廣泛且重要的應用,最常見的應用如銀行轉賬業務、電子商務支付業務等等。但是,值得注意的是,MySQL 的事務處理功能在 MYSIAM 存儲引擎中是不支持的,在 InnoDB 存儲引擎中是支持的。現在上傳一段代碼,作為引導認識 MySQL 事務處理的開始,簡單的實例,但融匯思想,相信會有很大的幫助。
?php $conn=mysql_connect(localhost , root , yourpassword)or die(mysql_error()); mysql_select_db(transaction ,$conn); mysql_query( set names utf8 // 創建事務 mysql_query(START TRANSACTION) or die(mysql_error()); $sqlA= update A set account=account-1 if(!mysql_query($sqlA)){nbsp; nbsp; nbsp; mysql_query(ROLLBACK
) or exit(mysql_error());// 判斷當執行失敗時回滾 nbsp; exit(); $sqlB= update B set account=account+1 if(!mysql_query($sqlB)){nbsp; nbsp; nbsp; mysql_query(ROLLBACK
) or exit(mysql_error());// 判斷當執行失敗時回滾 nbsp; exit(); mysql_query(COMMIT
)or die(mysql_error());// 執行事務 mysql_close($conn); ?
看完上述內容,你們掌握如何在 mysql 中事務處理的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注丸趣 TV 行業資訊頻道,感謝各位的閱讀!
向 AI 問一下細節