- 时间:2020-01-29 00:49 编辑: 来源: 阅读:
- 扫一扫,手机访问
摘要:SQL Server误区30日谈 第26天 SQL Server中存在真正的“事务嵌套”
误区 #26: SQL Server中存在真正的“事务嵌套”
错误
嵌套事务可不会像其语法表现的那样看起来允许事务嵌套。我真不知道为什么有人会这样写代码,我唯一能够想到的就是某个哥们对SQL Server社区嗤之以鼻然后写了这样的代码说:“玩玩你们”。
让我更详细的解释一下,SQL Server允许你在一个事务中开启嵌套另一个事务,SQL Server允许你提交这个嵌套事务,也允许你回滚这个事务。
但是,嵌套事务并不是真正的“嵌套”,对于嵌套事务来说SQL Server仅仅能够识别外层的事务。嵌套事务是日志不正常增长的罪魁祸首之一因为开发人员以为回滚了内层事务,仅仅是回滚内层事务。
但实际上当回滚内层事务时,会回滚整个事务,而不是仅仅是内层。这也是为什么我说嵌套事务并不存在。
所以作为开发人员来讲,永远不要对事务进行嵌套。事务嵌套是邪恶的。
如果你不相信我说的,那么通过下面的例子就就会相信。创建完数据库和表之后,每一条记录都会导致日志增加8K。
[url=http://msdn.microsoft.com/en-us/library/ms181299.aspx]Books Online[/url]来看,我只能使用外部事务的名称或是将事务名称留空来进行回滚,代码如下:
[url=http://msdn.microsoft.com/en-us/library/ms181299.aspx]Books Online[/url]所言,这个回滚操作将外部事务进行了回滚并将全局变量@@TRANCOUNT设置为0。事务中所有的修改都被回滚,如果想部分回滚的话只能使用SAVE TRAN 和ROLLBACK TRAN。
[b]测试 #2:嵌套事务中内部事务提交后会保存内部事务的修改吗?
[/b]
[url=http://www.sqlskills.com/BLOGS/PAUL/post/How-do-checkpoints-work.aspx]How do checkpoints work and what gets logged[/url])。提交内部事务不会导致日志被清除,这是由于外部事务回滚时也会连同内部事务一起回滚(译者注:所以这部分VLF在外部事务提交之前永远不会被标记位reusable)。所以这部分日志在外部事务提交之前永远不会被截断。为了证明这一点,我提交外部事务,然后再来看日志:
COMMIT TRAN OuterTran;
GO
CHECKPOINT;
GO
DBCC SQLPERF ('LOGSPACE');
GO
[img]http://files.jb51.net/file_images/article/201301/201319215752186.gif[/img]
么样,日志使用百分比大幅下降了吧。
对于嵌套事务来说---Just Say no。(这句话你可以当作来自SQLSkill.com的一个热心的家伙给的福利:-)
微信版

扫一扫进微信版
返回顶部