Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SAP Sybase SQL Anywhere 16.0 (中文) » SQL Anywhere 服务器 - SQL 用法 » 事务和隔离级别 » 隔离级别教程 » 教程:了解脏读

 

第 1 课:创建脏读

创建脏读,即销售经理正在更新价格的同时会计在进行计算。会计在计算时使用的是销售经理已经输入但正在进行改正的错误信息。

前提条件

本课假定您拥有在教程教程:了解脏读开头的特权部分中列出的角色和特权。

 任务
  1. 销售经理执行以下语句,将所有 T 恤衫的价格提高 $0.95:

    UPDATE GROUPO.Products
       SET UnitPrice = UnitPrice + 95
       WHERE Name = 'Tee Shirt';
    SELECT ID, Name, UnitPrice
       FROM GROUPO.Products;

    将返回以下结果集:

    ID Name UnitPrice
    300 Tee Shirt 104.00
    301 Tee Shirt 109.00
    302 Tee Shirt 109.00
    400 Baseball Cap 9.00
    ... ... ...

    销售经理很快发现应输入 0.95 而不是 95,但在改正错误之前,会计在另一个办公室访问了该数据库。

  2. 公司的会计担心存货会占用太多资金。作为会计,执行以下语句计算所有库存商品的总零售额:

    SELECT SUM( Quantity * UnitPrice )
     AS Inventory
       FROM GROUPO.Products;

    将返回以下结果集:

    Inventory
    21453.00

    可惜的是,计算出的结果并不准确。由于销售经理不小心将 T 恤衫的价格提高了 $95,结果反映了这个错误的价格。这个错误演示了一种被称作脏读的典型不一致类型。会计访问了销售经理已经输入但尚未提交的数据。

  3. 销售经理回退第一次所做的更改,然后输入正确的 UPDATE 语句,即可改正错误。检查新值是否正确。

    ROLLBACK;
    UPDATE GROUPO.Products
    SET UnitPrice = UnitPrice + 0.95
    WHERE NAME = 'Tee Shirt';

    将返回以下结果集:

    ID Name UnitPrice
    300 Tee Shirt 9.95
    301 Tee Shirt 14.95
    302 Tee Shirt 14.95
    400 Baseball Cap 9.00
    ... ... ...
  4. 会计并不知道他计算出的金额不正确。您可以在会计的窗口中再次执行 SELECT 语句查看正确的值。

    SELECT SUM( Quantity * UnitPrice )
     AS Inventory
       FROM GROUPO.Products;
    Inventory
    6687.15
  5. 在销售经理的窗口中完成事务。销售经理应输入 COMMIT 语句使更改成为永久更改,但您应该执行 ROLLBACK 语句,以避免更改 SQL Anywhere 示例数据库的本地副本。

    ROLLBACK;

结果

由于数据库服务器并发处理销售经理的工作和会计的工作,因此会计在不知情的情况下从数据库中得到了错误的信息。