生產環境中事務的應用場景:
事務是多個資料庫操作的集合,該集合內必須所有的資料庫操作完成,事務才能完成,只要有一個操作失敗,事務就不會成功,之前成功的資料庫操作會進行回滾以保證事務的完整性不會遭到破壞,因此事務具有不錯的安全性!
事務的四個特性,簡稱為ACID,這是這四個特性的英文頭個字母,
一:原子性(Atomic)
所謂原子性就是指的事務的不可分割性,原子是最小的單位,所以理解事務的原子性就是理解事務無法進行分割,事務里的資料庫操作要么全部成功,要么全部失敗,不可能出現一部分成功,一部分失敗的情況,這就是原子性,
二:一致性(Consistent)
事務操作會確保資料庫狀態保持一致性,事務提交前和提交后資料庫狀態會發生改變,但會保持一致性,例如購買商品,一旦完成一筆交易的事務,資料庫里的商品數必然減1,同時商店收益必然增加,這就是保持了資料庫狀態的一致性,
三:隔離性(Isolated)
隔離性指的是事務間是相互獨立的,不會互相影響,例如點餐程序為一個事務,從電話訂購到做出飯菜送餐完成結算完成所有這些操作為一個事務,不同的人進行點餐操作都是相互獨立的,并不會互相影響,這就是事務的隔離性,如果一個事務影響了其他的事務,其他的事務將會進行回滾,就如上面的點餐例子,如果飯菜已經賣完,最后點餐的事務將會影響后面的事務,因為沒有餐可點了,那么后面的事務將會回滾,
四:持久性(durable)
事務提交的結果或者效果在出現各種故障(例如斷網、服務器出問題之類的)的情況依舊能夠保存下來,這就是事務的持久性,
選擇合理的存盤引擎操作事務
InnoDB 是事務型資料庫的首選引擎,支持事務安全表 ACID
MySQL 5.7 以后默認 InnoDB 引擎;
MySQL 5.5 以前默認 MyISAM引擎, 需事務處理時,另設定InnoDB引擎;
查看當前的默認引擎:
show engines;

針對已經設定過的表,如何修改存盤引擎:
alter table stu engine = 'innodb';
或者直接圖形化軟體里修改,比如我的navicat

事務單獨開啟機制:
開始一個事務
start transaction或者begin
回退一個事務
rollback(全部回退)
提交一個事務
commit
全域事務使用方法:
set autocommit=0或者1 //0為不自動提交,1為自動提交,默認為1
這里autocommit也可以直接在mysql的組態檔里更改,windows是改my.ini檔案,linux是改my.cnf檔案
在[mysqld]下加入autocommit=0/1即可,
set autocommit = 0; insert into lesson(lesson) values('php'); commit;
php中使用事務的實體:
<?php $config = [ 'host' => '127.0.0.1', 'user' => 'root', 'password' => '123456', 'database' => 'fa', 'charset' => 'utf8' ]; $dns = sprintf( "mysql:host=%s;dbname=%s;charset=%s", $config['host'], $config['database'], $config['charset'], ); // echo $dns; try{ $pdo = new PDO($dns,$config['user'],$config['password']); // var_dump($pdo); $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); }catch(PDOException $e){ die($e->getMessage()); } // 演示事務 try{ $pdo->beginTransaction(); $pdo->exec('insert into stu(sname,class_id,sex) values("cyy10",2,"女")'); throw new Exception('沒有操作權限哦~'); $pdo->commit(); }catch(PDOException $e){ $pdo->rollBack(); die($e->getMessage()); }
事務隔離級別與臟讀實體:
查詢隔離級別
select @@tx_isolation;
在cmd界面登錄mysql,查詢事務隔離級別的時候,報錯:未知系統變數 'tx_isolation
解決辦法:
由于mysql資料庫的更新,在舊版本中tx_isolation是作為transaction_isolation的別名被應用的,新版本已經棄用了,所以輸入會顯示未知變數
把tx_isolation換成transaction_isolation,就可以顯示結果,

設定隔離級別
set session transaction isolation level read uncommitted;
臟讀指的是一個事務修改本事務的資料,但沒有提交的情況下,本事務可以查看到更改了卻沒有提交的資料,這種情況只可能發生在未提交讀readuncommitted的隔離級別里,
事務回滾后可以看到兩次讀取情況不一致;

高并發帶來的不可重復讀的隔離級別設定:
不重復讀:指的是一個事務多次讀取同一個資料,但此程序中第二個事務對第一個事務進行了修改,這就造成了第一個事務的多次讀取程序中的結果出現了前后不一致的情況,這就是不可重復讀!這個情況可以出現在read-uncommited和read-committed兩個隔離級別里!
幻讀實體操作與隔離級別處理:
在repeatable-read級別下解決了不可重復讀的問題,但是還有沒有解決的地方,那就是幻讀,幻讀是指在一個事務中,事務一對資料進行了更改并提交了,而事務二也對該資料進行了更改,但是更改的情況可能會受到事務一更改的影響,從而引起更改仿佛不存在,這就是幻讀!這是由于repeatable-read的隔離措施只讀取初次select的點導致的,
提交讀解決了臟讀問題,而重復讀解決了不重復讀的問題,串行化解決幻讀的問題,但是也會造成鎖競爭,可能造成大量的超時問題,因為串行化是給每個讀的資料行加上共享鎖,通過強制事務進行排序,以此防止相互沖突
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/203966.html
標籤:MySQL
下一篇:MySQL學習筆記(一)
