mysql事務操作 mysql的事務操作

2021-10-17 13:27:51 字數 2857 閱讀 6890

倒著思考。杜絕純粹的知識填鴨教育

少廢話,是上**:

update table1 set money-100 where id=1; //a賬戶減少100元

update table2 set money+100 where id=2; //b 賬戶增加100元

問題:這是乙個簡單的銀行轉賬案例sql,由於伺服器等未知原因,可能出現兩條sql乙個執行成功乙個執行失敗的情況下,乙個賬戶沒有成功增加100元,另乙個賬戶缺減少了100元。要實現這兩條sql語句必須都要成功或者都要失敗。請問讓你設計一種方案,怎麼去著手?

初步思考方案一:每條sql語句都加判斷,是否成功,失敗就不再往下走

if(!mysql_query(update table1 set money-100 where id=1)){

//失敗就停止退出

if(!mysql_query(update table1 set money-100 where id=1)){

//失敗就停止退出

總結:仔細想,如果第一條語句執行成功了,而第二條語句執行失敗了呢?

還不嚴謹。由此進一步考量,應該是無論哪條語句執行失敗,都要能撤銷已執行全部的操作。

設想:假如有這麼一條命令叫做rollback,可以撤銷已執行的全部操作。

那麼修改後的方案二:

if(!mysql_query(update table1 set money-100 where id=1)){

//撤銷

rollback

exit;

if(!mysql_query(update table1 set money-100 where id=1)){

//撤銷

rollback

exit;

總結:貌似應該沒問題了。再揣摩發現,我們撤銷操作,應該是撤銷到哪才算呢?不能把更早之前的所有執行的sql都撤銷掉吧,起碼有個位置。怎麼辦?在這兩條語句前,加乙個開始命令,只撤銷到開始位置。

設想:有乙個begin的開始命令。

那麼修改後的方案三:

mysql_query(begin)

if(!mysql_query(update table1 set money-100 where id=1)){

//撤銷

rollback

exit;

if(!mysql_query(update table1 set money-100 where id=1)){

//撤銷

rollback

exit;

總結:這下貌似是真的可以了,再仔細揣摩發現,還有點問題,假如第一條語句執行成功了,突然伺服器宕機了,命令沒有再往下走,仍然是不行的。怎麼辦?在末尾加乙個收尾的命令,如果mysql能執行到這條命令,那麼才算真正完成資料更新了,不然以前的操作還都不算。

設想:有乙個叫commit的收尾的命令

那麼修改後的方案四:

mysql_query(begin)

if(!mysql_query(update table1 set money-100 where id=1)){

//撤銷

rollback

exit;

if(!mysql_query(update table1 set money-100 where id=1)){

//撤銷

rollback

exit;

mysql_query(commit)

正著學習。彌補嚴謹自己的思維邏輯

學習下mysql中給我的解決方案,它把上述我們解決的問題叫做事務處理。

同樣mysql為了解決上述的問題,也有三個命令,分別是begin、rollback、commit

一樣的:

begin; //開啟事務

update table1 set money-100 where id=1; //a賬戶減少100元

update table2 set money+100 where id=2; //b 賬戶增加100元

commit; //提交事務

準確的說:凡是事務內的語句,只要能被mysql接收到,都能保證全部執行,但是但是並不能保證都執行成功。失敗時,需要自己主動去判斷主動去回滾。(極其錯誤的認知:認為只要把事務寫出來,最後用commit提交一下,資料庫會自動判斷這些語句是否全執行成功,如果成功則把所有的資料插入到資料庫,如果有一條失敗就自動回滾至原始狀態!)

嚴格的事務使用流程案例演示

if(!mysql_query(begin)){

//如果事務沒開啟成功,那麼後面的語句真的就是真實執行了,需要 主動判斷一下

//退出

exit;

if(!mysql_query(update table1 set money-100 where id=1)){

//回滾

rollback

// 退出

if(!mysql_query(update table2 set money+100 where id=2)){

//回滾

rollback

//退出

if(!mysql_query(commit)){

//回滾

rollback //如果客戶端把commit已經傳送到了mysql執行,失敗了,最好

也要判斷主動立即去回滾,雖然資料庫最終會慢慢自動回滾。因為事

務一直未提交,上面執行的寫操作語句會給當前運算元據鎖住,其

他使用者不能操作這條資料,直到等待事務結束才能。(提交或回滾)。

有時候,根據業務需要,我們對操作的資料需要保持乙個較高的一致性,可以考慮使用事務。

付費小密圈

1、解答大家php學習開發過程的問題

2、 分享不同php專案實戰經驗

3、定期邀請大牛進圈做知識分享

4、持續分享優質php知識教程

MySQL事務操作

在 mysql 命令列的預設設定下,事務都是自動提交的,即執行 sql 語句後就會馬上執行 commit 操作。因此要顯式地開啟乙個事務務須使用命令 begin 或 start transaction,或者執行命令 set autocommit 0,用來禁止使用當前會話的自動提交。菜鳥教程 1 用 ...

mysql事務操作

當把多個操作當做乙個事務時,這些操作具有一下特點 mysql select autocommit 檢視autocommit autocommit 1 1 row in set 0.00 sec mysql set autocommit 0 將autocommit設定為0,防止自動提交 query o...

MySQL事務操作

在 mysql 命令列的預設設定下,事務都是自動提交的,即執行 sql 語句後就會馬上執行 commit 操作。因此要顯式地開啟乙個事務務須使用命令 begin 或 start transaction,或者執行命令 set autocommit 0,用來禁止使用當前會話的自動提交。菜鳥教程 1 用 ...