加入收藏 | 设为首页 | 会员中心 | 我要投稿 上海站长网 (https://www.021zz.com.cn/)- 应用安全、建站、数据安全、媒体智能、运维!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

SQL Server 中的事务是什么

发布时间:2023-12-24 06:23:55 所属栏目:MsSql教程 来源:DaWei
导读: SQL Server 中的事务是一组被视为一个单元的 SQL 语句,它们按照“做所有事或不做任何事”的原则执行,成功的事务必须通过 ACID 测试。

事务的 ACID 属性是什么?
首字母缩写
SQL Server 中的事务是一组被视为一个单元的 SQL 语句,它们按照“做所有事或不做任何事”的原则执行,成功的事务必须通过 ACID 测试。

事务的 ACID 属性是什么?
首字母缩写词 ACID 是指事务的四个关键属性
原子性: Atomicity
一致性: Consistency
隔离性: Isolation
持久性: Durability

为了理解这一点,我们将使用以下两个表测试。
Product (产品表)
ProductID    Name    Price    Quantity
101    Laptop    15000    100
102    Desktop    20000    150
104    Mobile    3000    200
105    Tablet    4000    250
ProductSales (产品销售表)

ProductSalesID    ProductID    QuantitySold
1    101    10
2    102    15
3    104    30
4    105    35
请使用以下 SQL 脚本创建并使用示例数据填充 Product 和 ProductSales 表。

IF OBJECT_ID('dbo.Product','U') IS NOT NULL
    DROP TABLE dbo.Product
IF OBJECT_ID('dbo.ProductSales','U') IS NOT NULL
    DROP TABLE dbo.ProductSales
GO
CREATE TABLE Product
(
  ProductID INT PRIMARY KEY, 
  Name VARCHAR(40), 
  Price INT,
  Quantity INT
 )
GO
INSERT INTO Product VALUES(101, 'Laptop', 15000, 100)
INSERT INTO Product VALUES(102, 'Desktop', 20000, 150)
INSERT INTO Product VALUES(103, 'Mobile', 3000, 200)
INSERT INTO Product VALUES(104, 'Tablet', 4000, 250)
GO
CREATE TABLE ProductSales
(
  ProductSalesId INT PRIMARY KEY,
  ProductId INT,
  QuantitySold INT

GO
INSERT INTO ProductSales VALUES(1, 101, 10)
INSERT INTO ProductSales VALUES(2, 102, 15)
INSERT INTO ProductSales VALUES(3, 103, 30)
INSERT INTO ProductSales VALUES(4, 104, 35)
GO

SQL Server 中事务的原子性
SQL Server 中事务的原子性确保事务中的所有 DML 语句(即插入、更新、删除)成功完成或全部回滚。例如,在以下 spSellProduct 存储过程中,UPDATE 和 INSERT 语句都应该成功。如果 UPDATE 语句成功而 INSERT 语句失败,数据库应该通过回滚来撤消 UPDATE 语句所做的更改。

IF OBJECT_ID('spSellProduct','P') IS NOT NULL
    DROP PROCEDURE spSellProduct
GO
CREATE PROCEDURE spSellProduct
@ProductID INT,
@QuantityToSell INT
AS
BEGIN
  
  -- 首先我们需要检查待销售产品的可用库存
  DECLARE @StockAvailable INT
  SELECT @StockAvailable = Quantity FROM Product WHERE ProductId = @ProductId

  --如果可用库存小于要销售的数量,抛出错误
  IF(@StockAvailable < @QuantityToSell)
  BEGIN
    Raiserror('可用库存不足',16,1)
  END

  -- 如果可用库存充足
  ELSE
  BEGIN
    BEGIN TRY
      -- 我们需要开启一个事务
      BEGIN TRANSACTION

      -- 首先做减库存操作
      UPDATE Product SET Quantity = (Quantity - @QuantityToSell) WHERE ProductID = @ProductID

      -- 计算当前最大的产品销售ID,即 MaxProductSalesId
      DECLARE @MaxProductSalesId INT
      SELECT @MaxProductSalesId = CASE 
          WHEN MAX(ProductSalesId) IS NULL THEN 0 
          ELSE MAX(ProductSalesId) 
          END 
      FROM ProductSales

      -- 把 @MaxProductSalesId 加一, 所以我们会避免主键冲突 
      --(解释下,建表的时候,没有设置主键自增,所以需要人工处理自增)
      Set @MaxProductSalesId = @MaxProductSalesId + 1

      -- 把销售的产品数量记录到ProductSales表中
      INSERT INTO ProductSales VALUES (@MaxProductSalesId, @ProductId, @QuantityToSell)

      -- 最后,提交事务
      COMMIT TRANSACTION
    END TRY

    BEGIN CATCH
      -- 如果发生了异常,回滚事务
      ROLLBACK TRANSACTION
    END CATCH

  End
END
 

(编辑:上海站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章