事務處理是大型應用像銀行,支付寶寶這類應用可能會用到的,就是當我們數據處理不成功能時要把數據清除回滾,下面我來介紹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結束.
注意當你結束這個事務的同時也開啟了個新的事務,按第一種方法只將當前的作為一個事務.
只有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 UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE
1、不帶SESSION、GLOBAL的SET命令
只對下一個事務有效
2、SET SESSION
為當前會話設置隔離模式
3、SET GLOBAL
為以后新建的所有MYSQL連接設置隔離模式(當前連接不包括在內)
隔離模式:READ UNCOMMITTED
不隔離SELECT,其他事務未完成的修改(未COMMIT),其結果也考慮在內
READ COMMITTED
把其他事務的 COMMIT 修改考慮在內,同一個事務中,同一 SELECT 可能返回不同結果.
REPEATABLE READ(默認)
不把其他事務的修改考慮在內,無論其他事務是否用COMMIT命令提交過,同一個事務中,同一 SELECT 返回同一結果,前提是本事務,不修改.
SERIALIZABLE,和REPEATABLE READ類似,給所有的SELECT都加上了 共享鎖,一般MYSQL數據庫默認的引擎是MyISAM,這種引擎不支持事務,如果要讓MYSQL支持事務,可以自己手動修改.
方法如下:1.修改c:/appserv/mysql/my.ini文件,找到skip-InnoDB,在前面加上#,后保存文件.
2.在運行中輸入:services.msc,重啟mysql服務。
3.到phpmyadmin中,mysql->show engines;(或執行mysql->show variables like 'have_%'; ),查看InnoDB為YES,即表示數據庫支持InnoDB了,也就說明支持事務transaction了.
4.在創建表時,就可以為Storage Engine選擇InnoDB引擎了,如果是以前創建的表,可以使用mysql->alter table table_name type=InnoDB;
或 mysql->alter table table_name engine=InnoDB;來改變數據表的引擎以支持事務.
原理,代碼如下:
- function Tran( $sql ) {
- $judge = 1;
- mysql_query('begin');
- foreach ($sql as $v) {
- if ( !mysql_query($v) ) {
- $judge = 0;
- }
- }
- if ($judge == 0) {
- mysql_query('rollback');
- return false;
- }
- elseif ($judge == 1) {
- mysql_query('commit');
- return true;
- }
- }
例,代碼如下:
- <?php
- $handler=mysql_connect("localhost","root","");
- mysql_select_db("task");
- mysql_query("SET AUTOCOMMIT=0");//設置為不自動提交,因為MYSQL默認立即執行
- mysql_query("BEGIN");//開始事務定義
- if(!mysql_query("insert into trans (id) values('2')"))
- {
- mysql_query("ROOLBACK");//判斷當執行失敗時回滾
- }
- if(!mysql_query("insert into trans (id) values('4')"))
- {
- mysql_query("ROOLBACK");//判斷執行失敗回滾
- } //Vevb.com
- mysql_query("COMMIT");//執行事務
- mysql_close($handler);
- ?>
新聞熱點
疑難解答