【发布时间】:2011-03-06 07:59:52
【问题描述】:
SQL事务用于插入、更新,但它应该用于读取记录吗?
【问题讨论】:
-
感谢所有回答者,我希望可以选择将所有内容标记为答案,但没有。感谢您提供示例,提供锁定解释的链接,以及如何以毫秒为单位更新数据的解释,谢谢。
标签: c# sql sql-server-2005
SQL事务用于插入、更新,但它应该用于读取记录吗?
【问题讨论】:
标签: c# sql sql-server-2005
可以进行交易,但其目的是什么?
您可以使用 SET TRANSACTION ISOLATION LEVEL 语句为整个 SQL Server 会话设置适当的隔离级别。
这是 SQL Server 联机丛书中的语法:
SET TRANSACTION ISOLATION LEVEL
{
READ COMMITTED
| READ UNCOMMITTED
| REPEATABLE READ
| SERIALIZABLE
}
【讨论】:
纯读取不需要事务包装。
在您的 SQL 语句中,锁定提示应注意向您返回正确的数据 (http://msdn.microsoft.com/en-us/library/aa213026%28SQL.80%29.aspx)。
在服务器级别,您可以设置事务隔离级别 (http://msdn.microsoft.com/en-us/library/ms173763.aspx)。
编辑
解释纯读
如果你所有的 SQL 语句都有这些类型的读取,那么你不需要包装在事务中
SELECT Col1, Col2
From Table1
INNER JOIN Table2
ON Table1.Id = Table2.Table1Id
如果您正在读取可能受其他并行事务影响的结果,那么您必须包装在一个事务中。例如:
BEGIN TRANSACTION
INSERT INTO AccountTransactions (Type, Amount) Values ('Credit', 43.21)
UPDATE AccountSummary SET Balance = Balance + 43.21
SELECT @Balance = Balance FROM AccountSummary
COMMIT TRANSACTION
确实,您只是退回余额,但整个货币交易必须在两个地方进行。
【讨论】:
SELET <blah> 语句中。
当一个逻辑事务实际上映射到多个 SQL 查询时,事务旨在避免并发问题。例如,对于银行账户,如果您将资金从一个账户转移到另一个账户,您将首先从账户中减去金额,然后将其添加到另一个账户(反之亦然)。但是,如果在您的数据库之间发生一些错误,您的数据库将处于无效状态(您可能已经从一个帐户中减去了金额,但没有将其添加到另一个帐户)。因此,如果您在一个查询中读取所有数据,则不需要事务。
【讨论】:
当您在事务中修改了某些内容时,您可以在提交之前使用 read 语句检查操作是否生效。
【讨论】:
不,读取数据通常不需要事务,它也会减慢您的数据读取速度。
我建议您阅读 ATOMIC 一词。这将帮助您了解交易的用途。
【讨论】:
如果您在单个查询中查询所有记录,然后一次性将它们拉回,则没有必要。一切都包含在隐式事务中。也就是说,即使你取回了 100 万条记录,即使其他进程正在更改记录,你也会看到所有 100 万条记录在同一时间点的样子。
在只读进程中真正需要事务(通常还需要特定的锁定提示)的唯一情况是:
- 您阅读记录“零碎”并且在迭代时不需要其他任何东西来更改值。 [例如 ADO 中连接的记录集,然后您将光标通过。]
- 您读取了一些数据,进行了一些计算,然后读取了一些相关数据,但假设同时没有任何变化。
简而言之,当您希望阻止其他进程在 SQL 语句之间干扰您的数据时,您需要事务。
【讨论】:
如果您需要最新的毫秒信息,您可以使用由TransactionOptions 构造的事务,该事务具有IsolationLevel 或Serializable。
这会影响性能,因为它会锁定表(或表的一部分),所以你需要弄清楚你是否真的需要这个。
对于大多数用途,如果您正在执行读取操作,则不需要围绕它包装事务(假设您只在一个操作中执行读取操作)。
这实际上取决于您的应用程序、它需要什么数据以及如何使用它。
例如,如果您进行读取并根据结果进行写入或更新,但您刚刚读取的数据是最新的至关重要,您可能应该将整个逻辑包装到单个事务中。
【讨论】: