MySQL---事務知識,你搞明白沒有?

来源:http://www.cnblogs.com/ivanpan/archive/2017/03/31/6653990.html
-Advertisement-
Play Games

MySQL - 事務 在學習事務這一概念前,我們需要需要構思一個場景 場景構思 假設該場景發生於一個銀行轉賬背景下,月中,又到了發工資的日子。潭州教育科技集團打算給Tuple老師發放一個月的工資。(此處,我們假設轉賬都是由人工操作的),整個過程本應該如下: 公司財務核對Tuple老師工資單 確認公司 ...


MySQL - 事務

在學習事務這一概念前,我們需要需要構思一個場景

場景構思

假設該場景發生於一個銀行轉賬背景下,月中,又到了發工資的日子。潭州教育科技集團打算給Tuple老師發放一個月的工資。(此處,我們假設轉賬都是由人工操作的),整個過程本應該如下:

  1. 公司財務核對Tuple老師工資單

  2. 確認公司賬上還有這麼多錢

  3. 向銀行提出轉賬申請,銀行扣除公司財務卡上的指定金額

  4. 銀行向Tuple老師工資卡打入指定金額

  5. 銀行彙報雙方交易完成

    但是,當這個過程執行完第3步的時候,突然大斷電!整個電力系統進入癱瘓。待電力系統回覆之後,銀行並不會繼續執行4、5步甚至連1,2,3步的操作記錄都丟失了。此時出現瞭如下的問題:

  • 公司認為,工資已經發出

  • Tuple老師認為,公司還沒有發工資

  • 銀行認為,從來就沒有發生過轉賬的事情

    其實整個過程可以用一個詞來描述:資料庫中的數據產生了“不一致性”

一致性

上述背景中設計到了一個概念,叫做不一致性,這是和一致性相對的概念。那麼,什麼是一致性呢?

一致性的意思是,在一系列資料庫行為的前後兩個時間點上,數據是正確對應的。放在上面的例子來看,就是操作前後,兩個賬戶的總金額是一樣的,這樣就保證不會憑空的丟失掉不該丟失掉的金錢。

原子操作

為了保證數據的一致性,我們可以將一系列會破壞一致性的操作聲明為原子操作。被聲明為原子操作的那些操作要麼一起完成,要麼一起失敗,這樣我們就避免了類似斷電這類情況導致的數據不一致性。

事務

那麼如何才能實現MySQL中的原子操作呢?

MySQL以及大多數關係型資料庫都提供了一個叫做事務的技術。我們可以聲明一個事務的開始,在確認提交或者指明放棄前的所有操作,都先在一個叫做事務日誌的臨時環境中進行操作。待操作完成,確保了數據一致性之後,那麼我們可以手動確認提交,也可以選擇放棄以上操作。

註意: 一旦選擇了提交,那麼便不能再利用放棄操作來撤銷更改了。

案例分析

​ 我們首先創建我們本次案例需要使用的表,並給一些測試數據

 
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| python             |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
mysql> USE `python`;
Database changed
mysql> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| python     |
+------------+
1 row in set (0.00 sec)
mysql> CREATE TABLE `account` (
    ->   `id` int PRIMARY KEY AUTO_INCREMENT,
    ->   `name` VARCHAR(20) NOT NULL,
    ->   `balance` DECIMAL(12,2)
    -> );
Query OK, 0 rows affected (0.04 sec)
mysql> INSERT INTO `account`(`name`, `balance`)
    ->   VALUES ('TanzhouEDU', 10000000),('Tuple', 10000)
    -> ;
Query OK, 2 rows affected (0.70 sec)
Records: 2  Duplicates: 0  Warnings: 0

斷電案例(非原子操作)

首先,查看現有的賬戶情況

 
mysql> SELECT * FROM `account`;
+----+------------+-------------+
| id | user       | balance     |
+----+------------+-------------+
|  1 | TanzhouEDU | 10000000.00 |
|  2 | Tuple      |    10000.00 |
+----+------------+-------------+
2 rows in set (0.00 sec)

現在,潭州財務開始向Tuple老師發工資

mysql> UPDATE `account`
    ->   SET `balance` = `balance` - 10000
    ->   WHERE `user` = 'TanzhouEDU'
    -> ;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user       | balance    |
+----+------------+------------+
|  1 | TanzhouEDU | 9990000.00 |
|  2 | Tuple      |   10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)

此時,發生了斷電,再登錄資料庫以後,錢已經消失了。

事務案例(原子操作)

MySQL中,事務操作包括4個:

  • START TRANSACTION:開始一個新的事務

  • COMMIT:提交當前事務,做出永久改變

  • ROLLBACK:回滾當前事務,放棄修改

  • SET autocommit = {0 | 1}:對當前會話禁用(0)或啟用(1)自動提交模式

    我們利用事務機制來重覆上述斷電的情況。看看是否能夠有所幫助。

mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user       | balance    |
+----+------------+------------+
|  1 | TanzhouEDU | 9990000.00 |
|  2 | Tuple      |   10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE `account`
    ->   SET `balance` = `balance`-1000
    ->   WHERE `user` = 'TanzhouEDU'
    -> ;
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user       | balance    |
+----+------------+------------+
|  1 | TanzhouEDU | 9989000.00 |
|  2 | Tuple      |   10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
mysql> exit
Bye
tuple@MyVM:~$ mysql -utuple -p123456
mysql> USE `python`;
Database changed
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user       | balance    |
+----+------------+------------+
|  1 | TanzhouEDU | 9990000.00 |
|  2 | Tuple      |   10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)

我們可以看到,數據在斷電後,自動恢復到了數據修改前的樣子,它相當於如下一個操作過程。

 
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE `account`
    ->   SET `balance`=`balance`-1000
    ->   WHERE `user`='TanzhouEDU'
    -> ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user       | balance    |
+----+------------+------------+
|  1 | TanzhouEDU | 9989000.00 |
|  2 | Tuple      |   10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
mysql> ROLLBACK;
Query OK, 0 rows affected (0.02 sec)
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user       | balance    |
+----+------------+------------+
|  1 | TanzhouEDU | 9990000.00 |
|  2 | Tuple      |   10000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)

接著,我們來做一次正確的操作,真正的給Tuple老師發一次工資。

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE `account`
    ->   SET `balance` = `balance`-10000
    ->   WHERE `user` = 'TanzhouEDU'
    -> ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> UPDATE `account`
    ->   SET `balance` = `balance`+10000
    ->   WHERE `user`= 'Tuple'
    -> ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user       | balance    |
+----+------------+------------+
|  1 | TanzhouEDU | 9980000.00 |
|  2 | Tuple      |   20000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.03 sec)
mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM `account`;
+----+------------+------------+
| id | user       | balance    |
+----+------------+------------+
|  1 | TanzhouEDU | 9980000.00 |
|  2 | Tuple      |   20000.00 |
+----+------------+------------+
2 rows in set (0.00 sec)

通過上面的例子可以看出,一旦commit了,那麼rollback還是斷電都不能反悔了。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.[ ]的使用 當我們所要查的表是系統關鍵字或者表名中含有空格時,需要用[]括起來,例如新建了兩個表,分別為user,user info,那麼select * from user和select * from user info就要報錯,需要寫成:select * from [user] 和 sel ...
  • 問題SQL scwksmlcls.wk_cls_c , scwklrgcls.wk_lrg_cls_nm , scwkmdlcls.wk_mdl_cls_nm , scwksmlcls.wk_sml_cls_nm , scwksmlcls.wk_cls_rmk FROM screqrsnsws IN ...
  • 建表 在這裡呢我們先來建立兩張有外鍵關聯的張表。 CREATE DATABASE db0206; USE db0206; CREATE TABLE `db0206`.`tbl_dept`( `id` INT(11) NOT NULL AUTO_INCREMENT, `deptName` VARCHA ...
  • 在統計查詢中,經常會用到count函數,這裡是基礎的 MYSQL 行轉列 以及基本的聚合函數count,與group by 以及distinct組合使用 ...
  • 閱讀目錄 (1)選擇最有效率的表名順序(只在基於規則的優化器中有效) (2)WHERE子句中的連接順序 (3)SELECT子句中避免使用 ‘ * ‘ (4)減少訪問資料庫的次數 (5)在SQL*Plus , SQL*Forms和Pro*C中重新設置ARRAYSIZE參數, 可以增加每次資料庫訪問的檢 ...
  • 感慨一句,現在寫的sql語句自己是越來越看不懂了 。。。囧 使用場景:最近做畢設的時候碰見這麼一個場景(仿攜程網) 先看大的,按航班號查詢出3條數據。這個好弄 group by(航班)就行。點擊訂票,跳出兩個欄目,經濟艙和頭等艙分別帶餘票數。查航班餘票數好解決,條件那加 count(航班)就行。難點 ...
  • 本文出處:http://www.cnblogs.com/wy123/p/6646143.html SQLServer中開啟CDC之後,在某些情況下會導致事務日誌空間被占滿的現象為:在執行增刪改語句(產生事務日誌)的過程中提示,The transaction log for database '*** ...
  • 案例環境: 操作系統: Windows 2003 SE 32bit(SP2) 資料庫版本:Microsoft SQL Server 2005 - 9.00.5069.00 (Intel X86) Aug 22 2012 16:01:52 Copyright (c) 1988-2005 Microso... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...