我一直在读一些devs / dbas建议在所有数据库调用中使用事务,甚至是只读调用。虽然我理解在事务中插入/更新在事务中阅读的好处是什么?
答案 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。 “仅在必要时使用此选项。”
答案 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行。
两次交易:
将允许您正确执行此操作,而一次事务不能分开读取和写入操作,则不会使您进行提交而不会失去读者。