我们有这个代码,我想知道,在正常的Ado.net事务下它会实际锁定任何行吗?样品:
var sql1 = "SELECT MAX(entryNum) FROM tbl1 WHERE processNum = 1";
var cmd = new SqlCommand(sql1, conn, tran);
var newEntryNum = cmd.ExecuteScalar();
. . . . . .
var sql2 = "INSERT INTO tbl2 (entryNum) VALUES (" + newEntryNum + ")";
cmd = new SqlCommand(sql2, conn, tran);
在第一个select
中,它会锁定processNum = 1
的记录吗?对我来说,似乎没有任何东西会被锁定。是否有充分的理由按照交易的方式执行交易SELECT MAX
?
答案 0 :(得分:2)
通过锁定行,我认为你的意思是阻止另一个事务修改行?我之所以提到这一点是因为数据库会在不同的时间放置各种锁,导致不同的锁定行为。
在任何情况下,您的问题的答案都与编程语言或ADO.NET无关。它完全取决于用于事务的数据库和隔离级别。
例如,在SQL Server中,如果您以read committed
模式运行(这是我常说的),一旦select
查询完成,它将不会阻止另一个事务从processNum = 1
修改行。
但是,如果您处于repeatable read
或serializable
模式,那么执行select
查询会将锁定放在processNum = 1
的行上,这会阻止其他事务从修改行直到完成交易。
您可以在此处详细了解SQL Server如何为不同的隔离级别设置锁定:SET TRANSACTION ISOLATION LEVEL。
在之前的问题编辑中,您还想知道如何在Oracle数据库中处理这个问题。这很容易:无论您使用哪种隔离级别,读者永远不会阻止编写者,因此select
查询永远不会阻止其他事务修改行。