我有多个数据库会话,由于应用程序冻结,其中一个会话一直在阻止其他会话。在多个会话上运行事务。由于其他会话的锁定请求超时,我需要终止头部阻止程序。杀死该会话后,其他用户报告数据丢失。我很确定他们已经提交了他们的交易,但他们似乎仍然被回滚了。他们甚至可以证明它,因为一些文档已经打印出来,但后来丢失了数据。
由于另一个会话的回滚,提交的事务是否有可能被回滚?我不这么认为,但在阅读COMMIT 文档后,我有疑问。它说:
如果@@TRANCOUNT 大于 1,COMMIT TRANSACTION 只会将 @@TRANCOUNT 减 1,并且事务保持活动状态。
阅读TRANCOUNT 文档,它说:
返回在当前连接上发生的 BEGIN TRANSACTION 语句的数量。
那么当前连接是否与会话相同,或者多个会话可以共享同一个连接(也许通过池)?如果他们可以分享,这与交易有什么关系?这些活动事务是否会在稍后甚至在提交之后回滚?
[编辑] 更清楚的是,一些用户没有得到锁定超时,因为他们的数据与头部拦截器没有冲突。他们提交了事务,但在杀死头部阻止程序后,这些事务似乎已回滚。
[更新 2018-03-29]发生新事件后,我有机会在问题发生时进行调查。事务日志得出结论,问题是一个从未提交的嵌套事务。导致问题的应用程序并未冻结,因此用户在关闭应用程序之前从未注意到它。那时他丢失了他的数据,因为事务被回滚了。我接受了可能的最佳答案,那是告诉我不可能回滚已提交事务的答案。我想这真的不可能,只是很难找到真正的问题。
我需要在事务日志文件中查找一些特定事务,因此我使用 fn_dblog 函数。但该函数只返回几行。同时,我的数据库的 LDF 文件至少有几 GB。
我知道 fn_dblog 函数仅搜索日志的活动部分:
但是,这是什么意思?
事务日志的一部分何时变得不活动?
以及如何搜索不活动的部分?