如何进行脏读?

问题描述 投票:0回答:4

这是脏读的一个例子吗?

T1 & T2 交易

SET IMPLICIT_TRANSACTIONS OFF

Dirty read example

sql database t-sql transactions dirtyread
4个回答
2
投票

这是一个如何通过查看

MyCleanTable

构建“脏读”的示例
Id | Value
----------
1  | I am clean!
2  | I am clean!

  1. 使用未提交的隔离级别执行简单查询transaction_a

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
    
    BEGIN TRAN
    
        SELECT * FROM [MyCleanTable]
    

输出:

Id | Value
----------
1  | I am clean!
2  | I am clean!
  1. 使用 transaction_b 用脏值更新表:

     BEGIN TRAN
    
         UPDATE [ConcurrencyDemo].[dbo].[MyCleanTable]
         SET [Value] = 'I am dirty'  
         WHERE [Id] = 1 
    
  2. 在 transaction_a 中执行另一个查询并提交它:

        SELECT * FROM [ConcurrencyDemo].[dbo].[MyCleanTable]
    
    COMMIT;
    

输出:

Id | Value
----------
1  | I am dirty! ------> "dirty read"
2  | I am clean!
  1. 回滚transaction_b的更新:

    ROLLBACK;
    

在此阶段,表已回滚到其原始值:

Id | Value
----------
1  | I am clean!
2  | I am clean!

但是第 3 部分的查询读取到了脏值。


1
投票

这不是脏读。其作用的详细信息如下:隐式交易

要获得脏读,您需要将 select column1 from dbo.table1 WITH (NOLOCK)。 With (NOLOCK) 读取未提交的数据,如果事务以某种方式回滚,这些数据可能会消失并且永远不会真正存在。

获取脏读的另一种方法是使用:隔离级别读未提交。


1
投票

  1. 交易一开始
  2. 交易二开始
  3. 事务一进行更新操作
  4. 事务二做select操作,看到事务一产生的脏数据
  5. 事务一次提交或回滚

为了实现脏读,首先要执行以下命令

SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

0
投票
  • 脏读是一个事务读取了其他事务插入、更新或删除的未提交的数据。

我用 MSSQL(SQL Server)2 个命令提示符进行了脏读实验。

首先,我设置

READ UNCOMMITTED
隔离级别发生脏读

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

然后,我用

person
id
创建了
name
,如下所示。

person
表:

id 名字
1 约翰
2 大卫

现在,我使用 MSSQL 查询执行了以下步骤

流量 交易1(T1) 交易2(T2) 说明
步骤1
BEGIN;

GO;
T1开始。
第2步
BEGIN;

GO;
T2开始。
第3步
SELECT * FROM person WHERE id = 2;

GO;


2大卫
T1 读取为
David
第4步
UPDATE person SET name = 'Tom' WHERE id = 2;

GO;
T2 将
David
更新为
Tom
第5步
SELECT * FROM person WHERE id = 2;

GO;


2 汤姆
T1 在 T2 提交之前读取
Tom
而不是
David


*发生脏读!!

第6步
COMMIT;

GO;
T2 提交。
第7步
COMMIT;

GO;
T1 提交。
© www.soinside.com 2019 - 2024. All rights reserved.