mysql事务操作_mysql的事务操作
倒著思考。杜絕純粹的知識填鴨教育
少廢話,是上代碼:
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的事务操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql一张表最多多少索引_MySQL
- 下一篇: 释放mysql ibdata1文件_释放