MySQL的事務(wù)支持不是綁定在MySQL服務(wù)器本身,而是與存儲(chǔ)引擎相關(guān)
1.MyISAM:不支持事務(wù),用于只讀程序提高性能
2.InnoDB:支持ACID事務(wù)、行級(jí)鎖、并發(fā)
3.Berkeley DB:支持事務(wù)
一個(gè)事務(wù)是一個(gè)連續(xù)的一組數(shù)據(jù)庫操作,就好像它是一個(gè)單一的工作單元進(jìn)行。換言之,永遠(yuǎn)不會(huì)是完整的事務(wù),除非該組內(nèi)的每個(gè)單獨(dú)的操作是成功的。如果在事務(wù)的任何操作失敗,則整個(gè)事務(wù)將失敗。
實(shí)際上,會(huì)俱樂部許多SQL查詢到一個(gè)組中,將執(zhí)行所有的人都一起作為事務(wù)的一部分。
事務(wù)的特性:
事務(wù)有以下四個(gè)標(biāo)準(zhǔn)屬性的縮寫ACID,通常被稱為:
原子性: 確保工作單元內(nèi)的所有操作都成功完成,否則事務(wù)將被中止在故障點(diǎn),和以前的操作將回滾到以前的狀態(tài)。
一致性: 確保數(shù)據(jù)庫正確地改變狀態(tài)后,成功提交的事務(wù)。
隔離性: 使事務(wù)操作彼此獨(dú)立的和透明的。
持久性: 確保提交的事務(wù)的結(jié)果或效果的系統(tǒng)出現(xiàn)故障的情況下仍然存在。
在MySQL中,事務(wù)開始使用COMMIT或ROLLBACK語句開始工作和結(jié)束。開始和結(jié)束語句的SQL命令之間形成了大量的事務(wù)。
COMMIT ROLLBACK:
這兩個(gè)關(guān)鍵字提交和回滾主要用于MySQL的事務(wù)。
當(dāng)一個(gè)成功的事務(wù)完成后,發(fā)出COMMIT命令應(yīng)使所有參與表的更改才會(huì)生效。
如果發(fā)生故障時(shí),應(yīng)發(fā)出一個(gè)ROLLBACK命令返回的事務(wù)中引用的每一個(gè)表到以前的狀態(tài)。
可以控制的事務(wù)行為稱為AUTOCOMMIT設(shè)置會(huì)話變量。如果AUTOCOMMIT設(shè)置為1(默認(rèn)值),然后每一個(gè)SQL語句(在事務(wù)與否)被認(rèn)為是一個(gè)完整的事務(wù),并承諾在默認(rèn)情況下,當(dāng)它完成。 AUTOCOMMIT設(shè)置為0時(shí),發(fā)出SET AUTOCOMMIT =0命令,在隨后的一系列語句的作用就像一個(gè)事務(wù),直到一個(gè)明確的COMMIT語句時(shí),沒有活動(dòng)的提交。
可以通過使用mysql_query()函數(shù)在PHP中執(zhí)行這些SQL命令。
通用事務(wù)例子
這一系列事件是獨(dú)立于所使用的編程語言,可以建立在任何使用的語言來創(chuàng)建應(yīng)用程序的邏輯路徑。
可以通過使用mysql_query()函數(shù)在PHP中執(zhí)行這些SQL命令。
BEGIN WORK開始事務(wù)發(fā)出SQL命令
發(fā)出一個(gè)或多個(gè)SQL命令,如SELECT,INSERT,UPDATE或DELETE
檢查是否有任何錯(cuò)誤,一切都依據(jù)的需要。
如果有任何錯(cuò)誤,那么問題ROLLBACK命令,否則發(fā)出COMMIT命令。
在MySQL中的事務(wù)安全表類型:
如果打算使用MySQL事務(wù)編程,那么就需要一種特殊的方式創(chuàng)建表。有很多支持事務(wù)但最流行的是InnoDB表類型。
從源代碼編譯MySQL時(shí),InnoDB表支持需要特定的編譯參數(shù)。如果MySQL版本沒有InnoDB支持,請(qǐng)互聯(lián)網(wǎng)服務(wù)提供商建立一個(gè)版本的MySQL支持InnoDB表類型,或者下載并安裝Windows或Linux/UNIX的MySQL-Max二進(jìn)制分發(fā)和使用的表類型在開發(fā)環(huán)境中。
如果MySQL安裝支持InnoDB表,只需添加一個(gè)的TYPE=InnoDB 定義表創(chuàng)建語句。例如,下面的代碼創(chuàng)建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表類型,但它取決于您的安裝,如果它支持這兩種類型。
由于項(xiàng)目設(shè)計(jì)里面,牽扯到了金錢的轉(zhuǎn)移,于是就要用到MYSQL的事務(wù)處理,來保證一組處理結(jié)果的正確性。用了事務(wù),就不可避免的要犧牲一部分速度,來保證數(shù)據(jù)的正確性。
只有InnoDB支持事務(wù)
事務(wù) ACID Atomicity(原子性)、Consistency(穩(wěn)定性)、Isolation(隔離性)、Durability(可靠性)
1、事務(wù)的原子性
一組事務(wù),要么成功;要么撤回。
2、穩(wěn)定性
有非法數(shù)據(jù)(外鍵約束之類),事務(wù)撤回。
3、隔離性
事務(wù)獨(dú)立運(yùn)行。
一個(gè)事務(wù)處理后的結(jié)果,影響了其他事務(wù),那么其他事務(wù)會(huì)撤回。
事務(wù)的100%隔離,需要犧牲速度。
4、可靠性
軟、硬件崩潰后,InnoDB數(shù)據(jù)表驅(qū)動(dòng)會(huì)利用日志文件重構(gòu)修改。
可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit選項(xiàng) 決定什么時(shí)候吧事務(wù)保存到日志里。
開啟事務(wù)
START TRANSACTION 或 BEGIN
提交事務(wù)(關(guān)閉事務(wù))
放棄事務(wù)(關(guān)閉事務(wù))
折返點(diǎn)
SAVEPOINT adqoo_1
ROLLBACK TO SAVEPOINT adqoo_1
發(fā)生在折返點(diǎn) adqoo_1 之前的事務(wù)被提交,之后的被忽略
事務(wù)的終止
設(shè)置“自動(dòng)提交”模式
SET AUTOCOMMIT = 0
每條SQL都是同一個(gè)事務(wù)的不同命令,之間由 COMMIT 或 ROLLBACK隔開
掉線后,沒有 COMMIT 的事務(wù)都被放棄
事務(wù)鎖定模式
系統(tǒng)默認(rèn): 不需要等待某事務(wù)結(jié)束,可直接查詢到結(jié)果,但不能再進(jìn)行修改、刪除。
缺點(diǎn):查詢到的結(jié)果,可能是已經(jīng)過期的。
優(yōu)點(diǎn):不需要等待某事務(wù)結(jié)束,可直接查詢到結(jié)果。
需要用以下模式來設(shè)定鎖定模式
1、SELECT …… LOCK IN SHARE MODE(共享鎖)
查詢到的數(shù)據(jù),就是數(shù)據(jù)庫在這一時(shí)刻的數(shù)據(jù)(其他已commit事務(wù)的結(jié)果,已經(jīng)反應(yīng)到這里了)
SELECT 必須等待,某個(gè)事務(wù)結(jié)束后才能執(zhí)行
2、SELECT …… FOR UPDATE(排它鎖)
例如 SELECT * FROM tablename WHERE id200
那么id200的數(shù)據(jù),被查詢到的數(shù)據(jù),都將不能再進(jìn)行修改、刪除、SELECT …… LOCK IN SHARE MODE操作
一直到此事務(wù)結(jié)束
共享鎖 和 排它鎖 的區(qū)別:在于是否阻斷其他客戶發(fā)出的 SELECT …… LOCK IN SHARE MODE命令
3、INSERT / UPDATE / DELETE
所有關(guān)聯(lián)數(shù)據(jù)都會(huì)被鎖定,加上排它鎖
4、防插入鎖
例如 SELECT * FROM tablename WHERE id>200
那么id>200的記錄無法被插入
5、死鎖
自動(dòng)識(shí)別死鎖
先進(jìn)來的進(jìn)程被執(zhí)行,后來的進(jìn)程收到出錯(cuò)消息,并按ROLLBACK方式回滾
innodb_lock_wait_timeout = n 來設(shè)置最長等待時(shí)間,默認(rèn)是50秒
事務(wù)隔離模式
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL
READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE
1、不帶SESSION、GLOBAL的SET命令
只對(duì)下一個(gè)事務(wù)有效
2、SET SESSION
為當(dāng)前會(huì)話設(shè)置隔離模式
3、SET GLOBAL
為以后新建的所有MYSQL連接設(shè)置隔離模式(當(dāng)前連接不包括在內(nèi))
隔離模式
READ UNCOMMITTED
不隔離SELECT
其他事務(wù)未完成的修改(未COMMIT),其結(jié)果也考慮在內(nèi)
READ COMMITTED
把其他事務(wù)的 COMMIT 修改考慮在內(nèi)
同一個(gè)事務(wù)中,同一 SELECT 可能返回不同結(jié)果
REPEATABLE READ(默認(rèn))
不把其他事務(wù)的修改考慮在內(nèi),無論其他事務(wù)是否用COMMIT命令提交過
同一個(gè)事務(wù)中,同一 SELECT 返回同一結(jié)果(前提是本事務(wù),不修改)
SERIALIZABLE
和REPEATABLE READ類似,給所有的SELECT都加上了 共享鎖
出錯(cuò)處理
根據(jù)出錯(cuò)信息,執(zhí)行相應(yīng)的處理
mysql事物處理實(shí)例
MYSQL的事務(wù)處理主要有兩種方法
1.用begin,rollback,commit來實(shí)現(xiàn)
- begin開始一個(gè)事務(wù)
- rollback事務(wù)回滾
- commit 事務(wù)確認(rèn)
2.直接用set來改變mysql的自動(dòng)提交模式
- mysql默認(rèn)是自動(dòng)提交的,也就是你提交一個(gè)query,就直接執(zhí)行!可以通過
- set autocommit = 0 禁止自動(dòng)提交
- set autocommit = 1 開啟自動(dòng)提交
來實(shí)現(xiàn)事務(wù)的處理。
但要注意當(dāng)用set autocommit = 0 的時(shí)候,你以后所有的sql都將作為事務(wù)處理,直到你用commit確認(rèn)或 rollback結(jié)束,注意當(dāng)你結(jié)束這個(gè)事務(wù)的同時(shí)也開啟了新的事務(wù)!按第一種方法只將當(dāng)前的做為一個(gè)事務(wù)!
MYSQL只有 INNODB和BDB類型的數(shù)據(jù)表才支持事務(wù)處理,其他的類型是不支持的!
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事務(wù)處理
php代碼實(shí)現(xiàn)事務(wù)的處理可以通過PHP預(yù)定義類mysqli的以下方法實(shí)現(xiàn)。
- autocommit(boolean):該方法用于限定查詢結(jié)果是否自動(dòng)提交,如果該方法的參數(shù)為true則自動(dòng)提交,如果參數(shù)為false則關(guān)閉自動(dòng)提交。MySQL數(shù)據(jù)庫默認(rèn)為自動(dòng)提交。
- rollback():利用mysqli類中的該方法可以實(shí)現(xiàn)事務(wù)的回滾。
- commit():利用該方法可以實(shí)現(xiàn)提交所有查詢。
?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'); //建立數(shù)據(jù)庫連接
mssql_query("BEGIN TRANSACTION DEPS02_DEL"); //開始事務(wù)
$delete_dep_sql="DELETE FROM TBLDEPARTMENT WHERE DEPTID='{$_GET[deptid]}'";
// echo $delete_dep_sql."br>";
mssql_query($delete_dep_sql); //操作數(shù)據(jù)庫
// 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"); //提交事務(wù)
echo "alert('delete success!');";
}else{
mssql_query("ROLLBACK TRANSACTION DEPS02_DEL"); //回滾事務(wù)
echo "alert('delete faile!');";
}
echo "/script>";mssql_close();
?>
MySQL的事務(wù)處理在處理實(shí)際問題中有著廣泛且重要的應(yīng)用,最常見的應(yīng)用如銀行轉(zhuǎn)賬業(yè)務(wù)、電子商務(wù)支付業(yè)務(wù)等等。但是,值得注意的是,MySQL的事務(wù)處理功能在MYSIAM存儲(chǔ)引擎中是不支持的,在InnoDB存儲(chǔ)引擎中是支持的?,F(xiàn)在上傳一段代碼,作為引導(dǎo)認(rèn)識(shí)MySQL事務(wù)處理的開始,簡單的實(shí)例,但融匯思想,相信會(huì)有很大的幫助。
?php
$conn=mysql_connect('localhost','root','yourpassword')or die(mysql_error());
mysql_select_db('transaction',$conn);
mysql_query('set names utf8');
//創(chuàng)建事務(wù)
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());//判斷當(dāng)執(zhí)行失敗時(shí)回滾
nbsp; exit();
}
$sqlB="update B set account=account+1";
if(!mysql_query($sqlB)){
nbsp;nbsp;nbsp; mysql_query('ROLLBACK') or exit(mysql_error());//判斷當(dāng)執(zhí)行失敗時(shí)回滾
nbsp; exit();
}
mysql_query('COMMIT')or die(mysql_error());//執(zhí)行事務(wù)
mysql_close($conn);
?>
以上代碼可以作為模擬銀行轉(zhuǎn)賬業(yè)務(wù)的事務(wù)流程。以表A、B分別表示兩個(gè)已在銀行開戶的賬戶,當(dāng)賬戶A執(zhí)行轉(zhuǎn)出1元給賬戶B的操作時(shí),如果操作執(zhí)行失敗,轉(zhuǎn)出將會(huì)回滾至原始狀態(tài),不繼續(xù)向下執(zhí)行動(dòng)作。反之,如果操作執(zhí)行成功,則賬戶B可用余額將增加1元,否則事務(wù)回滾至原始狀態(tài)。
希望本文所述對(duì)你有所幫助,mysql事務(wù)處理用法與實(shí)例代碼內(nèi)容就給大家介紹到這里了。希望大家繼續(xù)關(guān)注我們的網(wǎng)站!想要學(xué)習(xí)mysql可以繼續(xù)關(guān)注本站。
您可能感興趣的文章:- Java實(shí)現(xiàn)的mysql事務(wù)處理操作示例
- PHP+MySQL高并發(fā)加鎖事務(wù)處理問題解決方法
- Mysql事務(wù)處理詳解
- NodeJs使用Mysql模塊實(shí)現(xiàn)事務(wù)處理實(shí)例
- php下pdo的mysql事務(wù)處理用法實(shí)例
- php實(shí)現(xiàn)mysql事務(wù)處理的方法
- MySQL事務(wù)處理與應(yīng)用簡析
- mysql 事務(wù)處理及表鎖定深入簡析