深入理解資料庫事務:確保數據完整性與一致性

来源:https://www.cnblogs.com/kxxz/archive/2023/08/21/17646515.html
-Advertisement-
Play Games

# 前言 在現代信息系統中,數據是至關重要的資產之一。作為一名後端開發人員,與資料庫的交道必不可少,為了確保數據的完整性、一致性和可靠性,資料庫引入了事務的概念。本次將帶您深入瞭解資料庫事務的重要性、特性以及如何在應用程式中正確地使用事務來維護數據的穩定性。 ## 什麼是資料庫事務? 資料庫事務是一 ...


前言

在現代信息系統中,數據是至關重要的資產之一。作為一名後端開發人員,與資料庫的交道必不可少,為了確保數據的完整性、一致性和可靠性,資料庫引入了事務的概念。本次將帶您深入瞭解資料庫事務的重要性、特性以及如何在應用程式中正確地使用事務來維護數據的穩定性。

什麼是資料庫事務?

資料庫事務是一組資料庫操作的集合,這些操作要麼全部成功執行,要麼全部失敗回滾。事務是資料庫管理系統(DBMS)中的核心概念,用於確保數據在併發訪問和操作時的一致性和完整性。

ACID 特性

事務通常遵循 ACID 特性,這是指:

  • 原子性(Atomicity):事務中的操作要麼全部成功,要麼全部失敗。如果任何操作失敗,整個事務都會回滾,保持數據的一致性。

假設您正在購物超市,您選擇了一些商品放入購物籃。原子性就像是您在結賬時,要麼所有商品都被正確地掃描和計算,要麼沒有商品被結賬,就像是所有商品一起被稱為一個“原子”單位。

  • 一致性(Consistency):事務將資料庫從一個合法狀態轉換為另一個合法狀態,不會違反數據完整性約束。

在購物過程中,超市會檢查您購物籃中的商品是否與價格一致,以確保不會因為錯誤標價而導致不一致的情況。一致性就像是超市保持商品和價格一致,您購買的商品總是符合預期。

  • 隔離性(Isolation):併發執行的事務相互隔離,一個事務的操作不會影響其他事務,直到事務提交才對其他事務可見。

想象您和朋友同時在超市購物,但您的購物籃和朋友的購物籃是分開的,互不幹擾。這就是隔離性,不同的購物籃(事務)在彼此之間是隔離的,不會相互干擾

  • 持久性(Durability):一旦事務提交,其對資料庫的更改將永久保存,即使系統崩潰也不會丟失。

假設您購買了商品並完成了結賬,超市會將您購買的記錄存檔,以備將來查詢。即使您離開超市,您的購買記錄仍然被保留,就像是您的購物信息被“持久”存儲

事務的基本操作

一個典型的事務通常包括以下步驟:

  1. 開始事務(BEGIN):事務開始前,DBMS 記錄當前狀態以備後用。

  2. 執行操作(Perform Operations):在事務內執行資料庫操作,如插入、更新、刪除等。

  3. 提交事務(COMMIT):如果事務內的所有操作都成功完成,可以將事務提交,將更改永久保存到資料庫中。

  4. 回滾事務(ROLLBACK):如果在事務執行期間發生錯誤,可以回滾事務,撤消之前的操作,將資料庫恢復到事務開始前的狀態。

事務的隔離級別

事務隔離級別控制了事務之間的可見性和併發行為。常見的隔離級別包括:

  • 讀未提交(Read Uncommitted):在這個隔離級別下,一個事務可以讀取其他事務尚未提交的數據。這可能導致臟讀(讀取了未提交的數據)、不可重覆讀(同一查詢在事務執行期間返回不同結果)和幻讀(事務在同一查詢中看到不同的數據行)等問題。讀未提交的隔離級別最不嚴格,可能會引發數據不一致問題

  • 讀已提交(Read Committed):在這個隔離級別下,一個事務只能讀取已經提交的數據,避免了臟讀問題。但是,不可重覆讀和幻讀問題仍然可能出現。因為其他事務可能在事務進行期間提交新的數據,導致不同時間點的查詢結果不一致。

  • 可重覆讀(Repeatable Read):可重覆讀隔離級別確保在同一事務內,同一個查詢的結果保持一致。這意味著一個事務中的查詢不會受到其他事務的修改影響。這可以防止臟讀和不可重覆讀問題,但幻讀問題仍然可能出現,因為其他事務可能插入新數據,導致新數據行的出現。

  • 串列化(Serializable):串列化是最嚴格的隔離級別,它確保每個事務都在獨立的時間段內執行,防止了併發問題。事務按照順序一個接一個地執行,這可以解決臟讀、不可重覆讀和幻讀問題。然而,串列化可能會對性能產生較大的影響,因為事務需要依次執行。


上面說到事務的隔離級別可以解決臟讀、幻讀、不可重覆讀的問題。那麼什麼是臟讀、幻讀、和不可重覆讀呢?

  • 臟讀(Dirty Read)
    臟讀指的是在一個事務中讀取了另一個事務未提交的數據。假設事務 A 修改了某一行數據,但還沒有提交。同時,事務 B 嘗試讀取了事務 A 修改的數據。如果事務 A 最終回滾了,那麼事務 B 讀取的數據就是不存在的,這就是臟讀。臟讀會導致不准確的數據展示,因為讀取的數據可能是臨時的、未經驗證的。

想象你正在製作一個蛋糕,但在製作過程中,你的朋友看了一眼,然後走了。在他離開之前,你還沒有完成蛋糕,但他已經看到了不完整的狀態。這就好像是一個“臟讀”:朋友讀取了還沒有完成的信息,結果可能是不准確或臨時的。

  • 不可重覆讀(Non-repeatable Read)
    不可重覆讀是指在同一個事務內,多次讀取同一數據時,得到不同的結果。這可能是因為在事務執行期間,其他事務修改了數據。例如,事務 A 在讀取某一行數據後,事務 B 修改了這行數據,並提交了。現在事務 A 再次讀取相同的數據,發現數據已經不同了,造成了不一致的現象。

假設你正在讀一本小說,當你讀到一部分內容時,有人偷偷地在書的後面添加了一些新章節。如果你再次閱讀同一部分,你會發現內容已經改變了,因為有新的內容被添加進來。這就像是“不可重覆讀”:同樣的數據在短時間內發生了變化,導致你得到了不同的結果。

  • 幻讀(Phantom Read)
    幻讀是指在同一個事務內,多次查詢同一範圍的數據時,得到不同的結果。這與不可重覆讀類似,但幻讀關註的是數據的數量變化。例如,事務 A 在查詢某個範圍內的所有數據時,事務 B 插入了新數據,並提交了。現在事務 A 再次查詢同一範圍的數據,發現數據行的數量增加了,這就是幻讀。

想象你正在草地上採摘草莓,你數了一下有多少個成熟的草莓。然後你去拿一個籃子,當你回來時,發現有一些新的草莓從草叢裡冒出來,導致總數增加了。這就是“幻讀”:同一範圍內的數據在短時間內發生了變化,導致數量發生了變化。

事務的傳播行為

事務的傳播行為是指在多個事務邊界交互時,一個事務如何與另一個事務進行交互和傳播。傳播行為定義了事務的範圍、邊界和嵌套關係,以確保事務的一致性和正確性。以下是幾種常見的事務傳播行為:

  • PROPAGATION_REQUIRED(需要事務)
    這是預設的傳播行為。如果當前沒有事務,就創建一個新事務;如果已經存在事務,就加入該事務。這意味著如果方法被調用時沒有事務,則會創建一個新事務。如果方法已經在事務中,則方法將使用已經存在的事務。這樣做可以保證事務嵌套。

這就像您和朋友在一起製作一張拼圖。如果朋友已經在拼圖上工作(存在事務),您會加入他的工作。如果沒有人在拼圖,您會創建一個新的拼圖,然後加入製作過程。這樣,無論之前是否有拼圖,您都可以保證最終拼圖是一張完整的。

  • PROPAGATION_REQUIRES_NEW(需要新事務)
    無論當前是否存在事務,都會創建一個新的事務。如果方法已經在事務中,則當前事務會被掛起,新事務將創建。這樣做可以在方法執行期間獨立於外部事務創建一個新的事務,確保完全隔離。

這就像您與朋友們一起在不同的活動中度過周末。無論朋友們在做什麼活動(存在事務),您都決定自己嘗試一項新活動,不受其他人的影響。您可以全身心地投入新的活動,不必擔心與其他活動的衝突。

  • PROPAGATION_NESTED(嵌套事務)
    如果當前存在事務,則在該事務內嵌套一個新事務。如果沒有事務,則行為類似於 PROPAGATION_REQUIRED。嵌套事務可以回滾到嵌套點,而不會影響外部事務。這樣可以實現更細粒度的事務管理。

想象您和家人一起做一個家庭項目,同時每個家庭成員也在做各自的小項目。您的小項目被嵌套在整個家庭項目中。您的項目可以獨立完成,但仍然受到家庭項目的影響。如果家庭項目失敗,您的項目也會受到影響。

  • PROPAGATION_SUPPORTS(支持事務)
    如果當前存在事務,則加入該事務;如果沒有事務,則以非事務方式執行。這意味著方法將根據調用方的上下文來決定是否執行在事務中。

這就像您加入一個跳繩團隊的訓練。如果其他人正在跳繩(存在事務),您可以選擇加入他們的活動。如果沒有人在跳繩,您可以以非正式的方式自己練習,不需要參與到團隊的事務中。

  • PROPAGATION_NOT_SUPPORTED(不支持事務)
    以非事務方式執行方法。如果當前存在事務,則將其掛起,方法執行完畢後恢複原事務。這樣可以保證方法的執行不受外部事務的影響。

這就像您在休閑時間去運動,不受任何工作的干擾。無論別人是否在工作,您可以專註於自己的活動,沒有事務的干擾。

  • PROPAGATION_MANDATORY(強制性的事務)
    必須在一個已存在的事務中執行,否則將拋出異常。這樣可以確保方法在事務上下文中被調用。

這就像您參加一個要求穿制服的活動。您必須穿制服(存在事務)才能參與,否則將無法參加。

  • PROPAGATION_NEVER(不允許事務)
    必須在非事務環境中執行,否則將拋出異常。這樣可以確保方法不會被錯誤地嵌套在事務中。

這就像您在一個休息時間內,被告知不能工作。無論其他人是否在工作,您不能參與到事務中。

如何正確使用事務?

在應用程式中,正確使用事務至關重要。以下是一些指導原則:

  1. 小而短的事務:將事務保持儘可能小和短,以減少對資料庫資源的鎖定時間,提高併發性能。

  2. 適當的隔離級別:選擇適當的隔離級別,平衡數據的一致性和性能需求。

  3. 異常處理:捕獲和處理事務中的異常,以便在錯誤發生時能夠正確地回滾事務。

  4. 批量操作:對大量數據進行操作時,考慮使用批量操作,減少事務的數量,提高性能。

  5. 事務嵌套:某些資料庫支持事務嵌套,但必須小心使用,確保正確的提交和回滾順序。

總結

事務是資料庫管理中保證數據一致性和完整性的重要工具。通過遵循 ACID 特性、正確使用事務操作和選擇適當的隔離級別,我們可以確保應用程式的數據在併發環境下保持穩定。深入理解和正確使用資料庫事務,將使您的應用更加可靠、穩定和高效。


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

-Advertisement-
Play Games
更多相關文章
  • 整體統一前端框架,使用VUE重新寫,支持Windows模式和傳統菜單導航模式切換。整體框架支持租戶,全面支持雲端部署與應用。全新界面設計,提升用戶的易用性。 ...
  • Woa(Wechat Official Account)是一個基於.net 7開發的微信公眾平臺介面項目,利用Supabase作為數據存儲和消息通信服務,同時提供了ChatGPT和Claude2等目前熱門的生成式AI會話功能接入。 ...
  • # ansible、Ad-Hoc、YAML劇本 ## 1.簡介 ansible是新出現的自動化運維工具,基於Python開發,集合了眾多運維工具(puppet、cfengine、chef、func、fabric)的優點,實現了批量系統配置、批量程式部署、批量運行命令等功能。 ## 2.部署 1.dn ...
  • 哈嘍大家好,我是鹹魚 文章《[SELinux 導致 Keepalived 檢測腳本無法執行](https://mp.weixin.qq.com/s?__biz=MzkzNzI1MzE2Mw==&mid=2247486319&idx=1&sn=4932d10d7ad39d02d2536be1a70b1 ...
  • [toc] # 最小化安裝Linux系統初始化腳本 **註:此腳本適用於centos 7/8、Ubuntu1804,具體需要根據實際情況進行測試調整。** 此腳本包含的功能: 1. 允許 root 用戶使用 ssh 登錄 2. 關閉 selinux 3. 關閉防火牆 4. 設置 ps1 5. 設置默 ...
  • 多摩川協議理解-(1) 多摩川編碼器有絕對值的和增量的兩種,這邊主要是我對多摩川絕對值的理解。 前文, 多摩川編碼器其實是日本有一家公司叫多摩川的公司做出來的,其實他們家有很多種編碼器,但是這裡我只對他的們出的協議作出理解。 硬體介面方面,因為有單圈和多圈只分,多圈一般有電池,所以會多一個帶電池的。 ...
  • 為什麼需要設備驅動模型 內核版本發展 2.4版本之前內核沒有統一的設備驅動模型,但是可以用(例如先前的led字元設備驅動實驗,使用前需要手動調用mknod命令創建設備文件,從而進一步控制硬體)。 2.4~2.6版本內核使用devfs,掛載在/dev目錄。需要在內核驅動中創建設備文件(調用devfs_ ...
  • ![](https://img2023.cnblogs.com/blog/3076680/202308/3076680-20230821142549307-1962607264.png) # 1. 命令行工具 ## 1.1. mysql -u root -p; ## 1.2. mysql> show ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...