欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

數(shù)據(jù)庫面試必備之MySQL中的樂觀鎖與悲觀鎖

 更新時(shí)間:2025年04月18日 10:53:26   作者:大明湖的狗凱.  
這篇文章主要介紹了數(shù)據(jù)庫面試必備之MySQL中樂觀鎖與悲觀鎖的相關(guān)資料,樂觀鎖適用于讀多寫少的場景,通過版本號(hào)檢查避免沖突,而悲觀鎖適用于寫多讀少且對(duì)數(shù)據(jù)一致性要求極高的場景,通過加鎖確保數(shù)據(jù)一致,需要的朋友可以參考下

一、引言

在多用戶并發(fā)訪問數(shù)據(jù)庫的場景中,數(shù)據(jù)的一致性和完整性至關(guān)重要。為了避免并發(fā)操作導(dǎo)致的數(shù)據(jù)沖突問題,MySQL 提供了樂觀鎖和悲觀鎖兩種并發(fā)控制機(jī)制。理解它們的工作原理、適用場景以及如何在實(shí)際代碼中運(yùn)用,對(duì)于開發(fā)高效且可靠的數(shù)據(jù)庫應(yīng)用程序具有關(guān)鍵意義。

二、樂觀鎖

(一)原理

樂觀鎖基于一種樂觀的假設(shè),即認(rèn)為在大多數(shù)情況下,并發(fā)事務(wù)之間不會(huì)發(fā)生沖突。它不會(huì)在事務(wù)開始時(shí)就對(duì)數(shù)據(jù)進(jìn)行加鎖,而是在提交數(shù)據(jù)更新之前,檢查數(shù)據(jù)是否在事務(wù)執(zhí)行期間被其他事務(wù)修改過。如果沒有被修改,則允許提交更新;如果發(fā)現(xiàn)數(shù)據(jù)已經(jīng)被修改,則根據(jù)具體的業(yè)務(wù)邏輯決定是重試更新操作還是拋出異常。

(二)應(yīng)用場景

樂觀鎖適用于讀多寫少的場景,因?yàn)樵谶@種情況下,并發(fā)沖突的概率相對(duì)較低。例如,在一個(gè)電商系統(tǒng)中,商品的瀏覽次數(shù)統(tǒng)計(jì)就是一個(gè)典型的讀多寫少的操作。多個(gè)用戶可以同時(shí)查看商品詳情頁面,而對(duì)瀏覽次數(shù)的更新相對(duì)較少。

(三)示例代碼

假設(shè)我們有一個(gè) products 表,其中包含 id(主鍵)、name、quantity 和 version 字段。version 字段將作為樂觀鎖的版本號(hào)。

-- 創(chuàng)建 products 表
CREATE TABLE products (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(50),
  quantity INT,
  version INT
);

以下是在 Java 代碼中使用樂觀鎖更新商品數(shù)量的示例:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class OptimisticLockingExample {
    public static void main(String[] args) {
        // 數(shù)據(jù)庫連接信息
        String url = "jdbc:mysql://localhost:3306/mydb";
        String username = "root";
        String password = "password";

        try (Connection connection = DriverManager.getConnection(url, username, password)) {
            // 開啟事務(wù)
            connection.setAutoCommit(false);

            // 查詢商品信息并獲取當(dāng)前版本號(hào)
            String selectSql = "SELECT quantity, version FROM products WHERE id =?";
            try (PreparedStatement selectStmt = connection.prepareStatement(selectSql)) {
                selectStmt.setInt(1, 1); // 假設(shè)要更新 id 為 1 的商品
                try (ResultSet resultSet = selectStmt.executeQuery()) {
                    if (resultSet.next()) {
                        int currentQuantity = resultSet.getInt("quantity");
                        int currentVersion = resultSet.getInt("version");

                        // 模擬業(yè)務(wù)邏輯,減少商品數(shù)量
                        int newQuantity = currentQuantity - 1;

                        // 更新商品數(shù)量和版本號(hào),使用樂觀鎖機(jī)制
                        String updateSql = "UPDATE products SET quantity =?, version = version + 1 WHERE id =? AND version =?";
                        try (PreparedStatement updateStmt = connection.prepareStatement(updateSql)) {
                            updateStmt.setInt(1, newQuantity);
                            updateStmt.setInt(2, 1); // 商品 id
                            updateStmt.setInt(3, currentVersion);
                            int rowsUpdated = updateStmt.executeUpdate();
                            if (rowsUpdated == 0) {
                                // 說明在更新之前數(shù)據(jù)被其他事務(wù)修改,樂觀鎖沖突
                                System.out.println("樂觀鎖沖突,更新失敗");
                                connection.rollback();
                            } else {
                                // 提交事務(wù)
                                connection.commit();
                                System.out.println("商品數(shù)量更新成功");
                            }
                        }
                    }
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

在上述代碼中,首先查詢商品的當(dāng)前數(shù)量和版本號(hào),然后根據(jù)業(yè)務(wù)需求計(jì)算新的數(shù)量。在更新時(shí),通過 WHERE 子句中的版本號(hào)條件來檢查數(shù)據(jù)是否被其他事務(wù)修改。如果更新的行數(shù)為 0,則表示發(fā)生了樂觀鎖沖突。

三、悲觀鎖

(一)原理

與樂觀鎖相反,悲觀鎖持一種悲觀的態(tài)度,認(rèn)為在并發(fā)環(huán)境中,數(shù)據(jù)很可能會(huì)被其他事務(wù)修改。因此,在事務(wù)開始時(shí),就對(duì)要操作的數(shù)據(jù)進(jìn)行加鎖,直到事務(wù)完成并提交或回滾后才釋放鎖。這樣可以確保在事務(wù)執(zhí)行期間,其他事務(wù)無法對(duì)鎖定的數(shù)據(jù)進(jìn)行修改操作。

(二)應(yīng)用場景

悲觀鎖適用于寫多讀少且對(duì)數(shù)據(jù)一致性要求極高的場景。例如,在銀行系統(tǒng)的轉(zhuǎn)賬操作中,涉及到對(duì)賬戶余額的修改,必須確保在整個(gè)轉(zhuǎn)賬事務(wù)過程中,賬戶余額數(shù)據(jù)不會(huì)被其他并發(fā)事務(wù)干擾,此時(shí)使用悲觀鎖可以有效避免數(shù)據(jù)不一致的問題。

(三)示例代碼

同樣以 products 表為例,在 MySQL 中可以使用 SELECT... FOR UPDATE 語句來實(shí)現(xiàn)悲觀鎖。

-- 開啟事務(wù)
START TRANSACTION;

-- 使用悲觀鎖查詢商品信息并鎖定行
SELECT quantity FROM products WHERE id = 1 FOR UPDATE;

-- 模擬業(yè)務(wù)邏輯,減少商品數(shù)量
UPDATE products SET quantity = quantity - 1 WHERE id = 1;

-- 提交事務(wù)
COMMIT;

在上述 SQL 代碼中,SELECT quantity FROM products WHERE id = 1 FOR UPDATE 語句會(huì)對(duì) id 為 1 的商品行進(jìn)行鎖定,直到事務(wù)提交或回滾。在鎖定期間,其他事務(wù)如果嘗試對(duì)該行數(shù)據(jù)進(jìn)行修改操作,將會(huì)被阻塞,直到鎖被釋放。

四、總結(jié)

樂觀鎖和悲觀鎖是 MySQL 中兩種重要的并發(fā)控制機(jī)制,它們各自適用于不同的應(yīng)用場景。在實(shí)際開發(fā)中,需要根據(jù)業(yè)務(wù)需求、數(shù)據(jù)讀寫比例以及對(duì)數(shù)據(jù)一致性的要求等因素,合理選擇使用樂觀鎖或悲觀鎖,以確保數(shù)據(jù)庫系統(tǒng)在高并發(fā)環(huán)境下能夠穩(wěn)定、高效地運(yùn)行,同時(shí)保證數(shù)據(jù)的完整性和一致性。

到此這篇關(guān)于數(shù)據(jù)庫面試必備之MySQL中的樂觀鎖與悲觀鎖的文章就介紹到這了,更多相關(guān)MySQL樂觀鎖與悲觀鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL約束攻擊的原理和復(fù)現(xiàn)方式

    MySQL約束攻擊的原理和復(fù)現(xiàn)方式

    這篇文章主要介紹了MySQL約束攻擊的原理和復(fù)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,
    2023-11-11
  • MySQL最新版8.1.0安裝配置教程(圖文)

    MySQL最新版8.1.0安裝配置教程(圖文)

    MySQL是一種廣泛使用的開源數(shù)據(jù)庫管理系統(tǒng),MySQL 8.0是最新版本,它具有更好的性能和安全性,本文主要介紹了MySQL最新版8.1.0安裝配置教程,感興趣的可以了解一下
    2023-09-09
  • Mysql關(guān)于數(shù)據(jù)庫是否應(yīng)該使用外鍵約束詳解說明

    Mysql關(guān)于數(shù)據(jù)庫是否應(yīng)該使用外鍵約束詳解說明

    MySQL 外鍵約束(FOREIGN KEY)是表的一個(gè)特殊字段,經(jīng)常與主鍵約束一起使用。對(duì)于兩個(gè)具有關(guān)聯(lián)關(guān)系的表而言,相關(guān)聯(lián)字段中主鍵所在的表就是主表,外鍵所在的表就是從表。外鍵用來建立主表與從表的關(guān)聯(lián)關(guān)系,為兩個(gè)表的數(shù)據(jù)建立連接,約束兩個(gè)表中數(shù)據(jù)的一致性和完整性
    2021-10-10
  • Ubuntu查看修改mysql的登錄名和密碼、安裝phpmyadmin

    Ubuntu查看修改mysql的登錄名和密碼、安裝phpmyadmin

    這篇文章主要介紹了Ubuntu查看修改mysql的登錄名和密碼、安裝phpmyadmin,本文分步驟給大家講解的非常詳細(xì),需要的朋友可以參考下
    2019-11-11
  • mysql數(shù)據(jù)庫之索引詳細(xì)介紹

    mysql數(shù)據(jù)庫之索引詳細(xì)介紹

    大家好,本篇文章主要講的是mysql數(shù)據(jù)庫之索引詳細(xì)介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • mysql設(shè)置遠(yuǎn)程訪問數(shù)據(jù)庫的多種方法

    mysql設(shè)置遠(yuǎn)程訪問數(shù)據(jù)庫的多種方法

    最近有一同學(xué)問我MySQL無法遠(yuǎn)程訪問怎么呢,但能使用localhost來進(jìn)行方法,下面腳本之家來給各位介紹一下解決辦法,需要的朋友可以參考下
    2013-10-10
  • mysql大批量插入數(shù)據(jù)的4種方法示例

    mysql大批量插入數(shù)據(jù)的4種方法示例

    這篇文章主要給大家介紹了關(guān)于mysql大批量插入數(shù)據(jù)的4種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用mysql具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • MySQL物理備份與恢復(fù)工具XtraBackup使用小結(jié)

    MySQL物理備份與恢復(fù)工具XtraBackup使用小結(jié)

    本文主要介紹了MySQL物理備份與恢復(fù)工具XtraBackup使用小結(jié),借助Percona XtraBackup工具實(shí)現(xiàn)MySQL的物理備份與恢復(fù),相當(dāng)于將整個(gè)MySQL進(jìn)行了復(fù)制,再粘貼到其他地方運(yùn)行,感興趣的可以了解一下
    2024-07-07
  • 在阿里云的CentOS環(huán)境中安裝配置MySQL的教程

    在阿里云的CentOS環(huán)境中安裝配置MySQL的教程

    這篇文章主要介紹了在阿里云的CentOS環(huán)境中安裝配置MySQL的教程,注意一下文章開頭所提到的系統(tǒng)自帶MariaDB的問題,需要的朋友可以參考下
    2015-12-12
  • sql查詢語句教程之插入、更新和刪除數(shù)據(jù)實(shí)例

    sql查詢語句教程之插入、更新和刪除數(shù)據(jù)實(shí)例

    如果要在程序運(yùn)行過程中操作數(shù)據(jù)庫中的數(shù)據(jù),那得先學(xué)會(huì)使用SQL語句,下面這篇文章主要給大家介紹了關(guān)于sql查詢語句教程之插入、更新和刪除數(shù)據(jù)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06

最新評(píng)論