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

SQL Anywhere 12.0.1 » SQL Anywhere 服务器 - SQL 的用法 » 事务和隔离级别 » 隔离级别教程 » 教程:了解幻像行

 

第 2 课:避免幻像行

 ♦ 使用快照隔离避免幻像行

您可以使用快照隔离级别维护与隔离级别 3 相同的一致性,而且不会造成任何种类的阻塞。销售经理的语句未被阻塞,会计也不会看到幻像行。

如果尚未执行幻像行教程中的第 1 步到第 4 步,请执行这些步骤。这些步骤介绍了如何启动两个 Interactive SQL 实例。请参见教程:了解幻像行

  1. 通过执行以下语句为会计启用快照隔离。

    SET OPTION PUBLIC. allow_snapshot_isolation = 'On';
    SET TEMPORARY OPTION isolation_level = 'snapshot';
  2. 在 [Accountant] 窗口中输入以下语句,列出所有部门。

    SELECT * FROM Departments
    ORDER BY DepartmentID;
    DepartmentID DepartmentName DepartmentHeadID
    100 R & D 501
    200 Sales 902
    300 Finance 1293
    400 Marketing 1576
    500 Shipping 703
  3. 销售经理决定设立一个新部门,专门管理国外市场。Philip Chin(EmployeeID 为 129)将作为这个新部门的经理。

    INSERT INTO Departments
       ( DepartmentID, DepartmentName, DepartmentHeadID )
       VALUES( 600, 'Foreign Sales', 129 );
    COMMIT;

    最后一个语句为这个新部门创建了一个新条目。这个条目作为新的一行出现在销售经理窗口中的表的底部。

    SELECT * FROM Departments
    ORDER BY DepartmentID;
    DepartmentID DepartmentName DepartmentHeadID
    100 R & D 501
    200 Sales 902
    300 Finance 1293
    400 Marketing 1576
    500 Shipping 703
    600 Foreign Sales 129
  4. 会计可以再次执行他的查询,并且不会看到新行,这是因为事务尚未结束。

    SELECT *
    FROM Departments
    ORDER BY DepartmentID;
    DepartmentID DepartmentName DepartmentHeadID
    100 R & D 501
    200 Sales 902
    300 Finance 1293
    400 Marketing 1576
    500 Shipping 703
  5. 而销售经理想要再增加一个部门来处理针对大型企业合作伙伴的销售业务。在销售经理的窗口中执行以下语句。

    INSERT INTO Departments
     ( DepartmentID, DepartmentName, DepartmentHeadID )
       VALUES( 700, 'Major Account Sales', 902 );

    销售经理的更改未被阻塞,因为会计在使用快照隔离。

  6. 会计必须结束他的快照事务,以查看销售经理提交到数据库的更改。

    COMMIT;
       SELECT * FROM Departments
       ORDER BY DepartmentID;

    现在会计看到了 Foreign Sales 部门,但没有看到 Major Account Sales 部门。

    DepartmentID DepartmentName DepartmentHeadID
    100 R & D 501
    200 Sales 902
    300 Finance 1293
    400 Marketing 1576
    500 Shipping 703
    600 Foreign Sales 129
  7. 为了避免更改 SQL Anywhere 示例数据,您应该回退未完成的插入 Major Account Sales 部门行的事务,并使用另一个事务删除 Foreign Sales 部门。

    1. 在销售经理的窗口中执行以下语句,回退最后的未完成事务:

      ROLLBACK;
    2. 同样在销售经理的窗口中,执行以下两条语句,删除之前插入的行并提交此操作。

      DELETE FROM Departments
      WHERE DepartmentID = 600;
      COMMIT;