暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL 事务的概念与特性

技术老小子 2024-04-09
3

1. 什么是事务?

在数据库管理系统中,事务是指一组数据库操作,这些操作要么全部执行成功,要么全部执行失败。事务可以确保数据库的一致性和完整性,以及支持并发访问和并发控制。

事务具有以下四个特性,通常被称为ACID特性:

  • 原子性(Atomicity):事务中的所有操作要么全部成功,要么全部失败。如果事务中的任何操作失败,那么整个事务将被回滚到初始状态,不会对数据库产生任何影响。

  • 一致性(Consistency):事务的执行不会破坏数据库的一致性。在事务开始之前和结束之后,数据库必须处于一致的状态。

  • 隔离性(Isolation):并发事务之间是相互隔离的,每个事务的操作对其他事务是不可见的。事务的隔离级别可以控制并发事务之间的可见性和影响。

  • 持久性(Durability):一旦事务被提交,其结果将永久保存在数据库中,即使在系统故障的情况下也不会丢失。

2. 事务的例子

为了更好地理解事务的概念与特性,我们来看一些例子。

2.1 转账事务

假设我们有一个银行应用程序,需要实现转账功能。当用户A向用户B转账时,我们希望这个操作是原子的,要么全部成功,要么全部失败。

首先,我们创建一个accounts
表来存储用户的账户信息:

    CREATE TABLE accounts (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    balance DECIMAL(10, 2)
    );
    复制
    复制

    然后,我们插入一些测试数据:

    复制
      INSERT INTO accounts (id, name, balance) VALUES (1, 'Alice', 1000.00);
      INSERT INTO accounts (id, name, balance) VALUES (2, 'Bob', 500.00);


      复制
      复制

      现在,我们可以使用事务来实现转账功能:

        DELIMITER //


        CREATE PROCEDURE TransferFunds()
        BEGIN
        START TRANSACTION;


        -- 查询用户A的余额
        SELECT balance INTO @balance_a FROM accounts WHERE id = 1;


        -- 查询用户B的余额
        SELECT balance INTO @balance_b FROM accounts WHERE id = 2;


        -- 检查用户A的余额是否足够
        IF @balance_a >= 100.00 THEN
        -- 更新用户A的余额
        UPDATE accounts SET balance = balance - 100.00 WHERE id = 1;


        -- 更新用户B的余额
        UPDATE accounts SET balance = balance + 100.00 WHERE id = 2;


        -- 提交事务
        COMMIT;
        ELSE
        -- 回滚事务
        ROLLBACK;
        END IF;
        END //


        DELIMITER ;
        复制
        复制
          -- 调用存储过程
          CALL TransferFunds();
          复制
          复制

          在这个例子中,我们首先查询用户A和用户B的余额。然后,我们检查用户A的余额是否足够进行转账。如果足够,我们更新用户A和用户B的余额,并提交事务。否则,我们回滚事务。

          2.2 订单事务

          假设我们有一个在线商店应用程序,需要实现下订单功能。当用户下订单时,我们希望将订单信息插入到orders
          表中,并从用户的账户中扣除相应的金额。

          首先,我们创建一个orders
          表来存储订单信息:

            CREATE TABLE orders (
            id INT PRIMARY KEY,
            user_id INT,
            total DECIMAL(10, 2)
            );
            复制
            复制

            然后,我们插入一些测试数据:

            复制
              INSERT INTO orders (id, user_id, total) VALUES (1, 1, 100.00);
              INSERT INTO orders (id, user_id, total) VALUES (2, 2, 200.00);


              复制
              现在,我们可以使用事务来实现下订单功能:
              复制
                DELIMITER //


                CREATE PROCEDURE ProcessOrder()
                BEGIN
                -- 开始事务
                START TRANSACTION;


                -- 查询订单信息
                SELECT total INTO @total FROM orders WHERE id = 1;


                -- 查询用户余额
                SELECT balance INTO @balance FROM accounts WHERE id = 1;


                -- 检查用户余额是否足够支付订单
                IF @balance >= @total THEN
                -- 插入订单信息(注意:这里的订单ID不应该硬编码为3,应该是动态生成的)
                INSERT INTO orders (user_id, total) VALUES (1, @total);


                -- 更新用户余额
                UPDATE accounts SET balance = balance - @total WHERE id = 1;


                -- 提交事务
                COMMIT;
                ELSE
                -- 回滚事务
                ROLLBACK;
                END IF;
                END //


                DELIMITER ;
                复制
                复制
                  -- 调用存储过程
                  CALL ProcessOrder();
                  复制
                  复制

                  在这个例子中,我们首先查询订单的总金额和用户的余额。然后,我们检查用户的余额是否足够支付订单。如果足够,我们插入订单信息,并更新用户的余额。最后,我们提交事务。如果用户的余额不足以支付订单,我们回滚事务。


                  文章转载自技术老小子,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                  评论