是否应该有读取查询的事务?

时间:2008-11-21 14:19:52

标签: sql-server transactions crud

我一直在读一些devs / dbas建议在所有数据库调用中使用事务,甚至是只读调用。虽然我理解在事务中插入/更新在事务中阅读的好处是什么?

6 个答案:

答案 0 :(得分:27)

因此,您可以获得数据库的一致视图。想象一下,你有两个相互链接的表,但出于某种原因你在pseuodocode中选择了两个...:

myRows = query(SELECT * FROM A)
moreRows = query(SELECT * FROM B WHERE a_id IN myRows[id])

如果在两个查询之间,有人更改B以删除某些行,则会出现问题。

答案 1 :(得分:3)

与RoBorg所说的相似,你可以用事务进行SELECTS,以防止在语句之间读取幻像数据。 但是重要的是要注意SQL Server中的默认事务隔离级别是READ COMMITTED,它只会阻止脏读;为了防止幻象数据,你必须至少使用REPEATABLE READ。 “仅在必要时使用此选项。”

http://msdn.microsoft.com/en-us/library/ms173763.aspx

答案 2 :(得分:1)

我发现'transaction'在不同的SQL服务器上表现得非常不同。在某些情况下,启动事务会锁定所有其他连接,使其无法执行任何SQL,直到提交或回滚事务为止(MS SQLServer 6.5)。其他人没有任何问题,只有在有修改(oracle)时才会锁定。锁甚至可以扩展为仅包含您的更改 - 单元锁/行锁/页锁/表锁。

通常,只有在必须维护多个insert / delete / update语句之间的数据完整性时才使用事务。即便如此,我更喜欢使用DB定义的级联删除来实现它,以便数据库自动和原子地执行此操作。

如果您可以预见到您想要回滚多个修改的情况,请使用事务,否则,数据库将执行原子更新,而无需额外的代码来处理它。

答案 3 :(得分:1)

过去几分钟我一直在检查这个问题,因为这是我应该了解的更多信息。这是我发现的。

当一个人正在阅读记录并且不希望它被修改或读取时,如果你想锁定该行,那么事务对于一个选择是有用的。例如,运行以下查询:

(在查询窗口1中)

BEGIN TRAN SELECT * FROM MYTABLE WITH(ROWLOCK XLOCK) WHERE ID = 1

(在查询窗口2中)

SELECT * FROM MYTABLE WHERE ID = 1

(查询窗口2在窗口1中运行之前不会返回结果)

COMMIT TRAN

有用的链接:

http://msdn.microsoft.com/en-us/library/aa213039.aspx

http://msdn.microsoft.com/en-us/library/aa213026.aspx

http://msdn.microsoft.com/en-us/library/ms190345.aspx

我的目标是获得阻止的东西 - 并且在将XLOCK添加到其中之后它终于起作用了。简单地使用ROWLOCK是行不通的。我假设它发布了一个共享锁(并且数据已被读取)..但我仍在探索这个。

添加 - WITH(UPDLOCK ROWLOCK) - 将允许您选择并锁定行以进行更新,这将有助于并发。

小心表格提示。如果您开始随意应用它们,如果您的应用程序上只有少量用户,您的系统将会慢慢爬行。在调查之前,这是我所知道的一件事;)

答案 4 :(得分:0)

我想说,交易的主要目的之一是提供回滚潜力,如果有任何问题 - 在简单阅读时就会失效。

答案 5 :(得分:0)

另一个要进行多次读取和插入事务的好理由是,您希望基于从选择查询中获得的数据插入记录,并且还希望提交插入的每个X行。

两次交易:

  1. 用于读取\选择。
  2. 插入并提交每个X行。

将允许您正确执行此操作,而一次事务不能分开读取和写入操作,则不会使您进行提交而不会失去读者。