当我正在阅读 ADO.NET 时另一个进程更新记录时会发生什么
What happens when another process updates a record while I'm reading in ADO.NET
假设我在 C# 中有这个脚本
....
string _commandStr = "SELECT * FROM products";
if (connection.State == System.Data.ConnectionState.Closed)
connection.Open();
SqlCommand cmd = new SqlCommand(_commandStr, connection);
var reader = cmd.ExecuteReader();
while (reader.Read())
{
...some expensive formatting operation. This cycle takes minutes
}
现在,如果另一个进程将 Record 附加到产品 table 而 READ 周期为 运行 会发生什么情况?在循环结束之前最终记录是否可用?
SELECT
查询是否返回新插入(和提交)的行取决于:
- 交易当前会话isolation level
- 读取已提交的快照数据库选项
- select 查询扫描点是在新行位置之前还是之后。
如果数据库中的 READ_COMMITTED
隔离级别关闭 READ_COMMITTED_SHAPSHOT
选项,则可能会或可能不会返回新行,具体取决于新插入的行是在 [= 之前还是之后10=]查询扫描点。
在启用 READ_COMMITTED_SHAPSHOT
选项的数据库中使用 READ_COMMITTED
隔离级别,将不会返回新行。查询结果反映了 SELECT
查询开始时的数据,因此不会返回新插入的行。
使用 SNAPSHOT
隔离级别,查询结果反映 SELECT
查询(或显式事务)开始时的数据,因此不会返回新插入的行。
使用 REPEATABLE_READ
隔离级别,可能会或可能不会返回新行,具体取决于新行是在 SELECT
查询扫描点之前还是之后插入。
使用 SERIALIZABLE
隔离级别,将不会返回新行,因为并发插入将在 SELECT
查询全扫描期间被阻止。
假设我在 C# 中有这个脚本
....
string _commandStr = "SELECT * FROM products";
if (connection.State == System.Data.ConnectionState.Closed)
connection.Open();
SqlCommand cmd = new SqlCommand(_commandStr, connection);
var reader = cmd.ExecuteReader();
while (reader.Read())
{
...some expensive formatting operation. This cycle takes minutes
}
现在,如果另一个进程将 Record 附加到产品 table 而 READ 周期为 运行 会发生什么情况?在循环结束之前最终记录是否可用?
SELECT
查询是否返回新插入(和提交)的行取决于:
- 交易当前会话isolation level
- 读取已提交的快照数据库选项
- select 查询扫描点是在新行位置之前还是之后。
如果数据库中的 READ_COMMITTED
隔离级别关闭 READ_COMMITTED_SHAPSHOT
选项,则可能会或可能不会返回新行,具体取决于新插入的行是在 [= 之前还是之后10=]查询扫描点。
在启用 READ_COMMITTED_SHAPSHOT
选项的数据库中使用 READ_COMMITTED
隔离级别,将不会返回新行。查询结果反映了 SELECT
查询开始时的数据,因此不会返回新插入的行。
使用 SNAPSHOT
隔离级别,查询结果反映 SELECT
查询(或显式事务)开始时的数据,因此不会返回新插入的行。
使用 REPEATABLE_READ
隔离级别,可能会或可能不会返回新行,具体取决于新行是在 SELECT
查询扫描点之前还是之后插入。
使用 SERIALIZABLE
隔离级别,将不会返回新行,因为并发插入将在 SELECT
查询全扫描期间被阻止。