我在 SQL Server 2012 中执行了以下查询:
create table testTransaction
(
id int
name varchar(100)
)
insert into testTransaction values (1,'ABC'),(2,'XYZ')
/* Query1 */
begin try
begin transaction
insert into testTransaction values (3,'FGH')
commit transaction
end try
begin catch
if @@trancount > 0
rollback transaction
end catch
我执行了 query1 并得到一个错误,我使用的帐户没有权限将值插入到该表中。在另一个窗口中,我尝试在 testTransaction 上进行选择,但查询一直在继续。
那时我意识到我在另一个窗口中运行的前一个查询有一个打开的事务。我去把它滚回来,一切都很好。
如果我关闭了具有打开事务的窗口而不回滚它会发生什么?事务是否会一直打开,直到有人手动回滚它,或者当窗口关闭时 SQL Server 是否回滚任何未提交的事务?
另外,我如何在任何会话中找出数据库中所有打开的事务?
假设当您说“会话窗口”时,您指的是 SSMS 中的查询窗口。在 SSMS 中,每个查询窗口通常都有自己的连接。当您关闭窗口时,理论上它会关闭连接。(理论上,因为它取决于连接是否用于连接池。)
当客户端和 SQL Server 之间的连接在打开的事务中被切断时,该事务将自动回滚。汉娜在开放事务回滚的所有方式是什么中的回答中指出了这一点?:“客户端或服务器或两者之间的任何基础设施断开连接”。
回答您的问题
在大多数 RDBMS 功能基于 ACID 原则的前提下,您的事务将被回滚。
(强调我的)
参考: 酸(维基百科)
关闭窗口应导致事务回滚以保证数据库事务的 ACID 属性。
SSMS中关闭查询窗口(实际案例)
在 SSMS 中,您会看到一个对话框,让您决定如何对关闭窗口做出反应:
通过Taskmanager强制关闭SSMS(实际案例)
当 SSMS 通过任务管理器终止和/或强制关闭时,事务会自动回滚。
这可以通过以下步骤重现:
在数据库中创建下表
打开一个 SSMS 并执行以下脚本:
打开第二个 SSMS 并执行以下脚本:
通过任务管理器杀死第一个 SSMS。
验证步骤 3 中的第二个脚本不显示任何数据。
...正如 JD 在他的链接答案中提到的那样。
在正常情况下,事务将被回滚。
要确定当前打开的事务,您可以查询、
sys.dm_exec_sessions
和其他系统管理视图以确定请求或会话中的任何打开的事务。sys.dm_exec_connections
sys.dm_exec_reuqests
示例脚本:
列将显示当前仍在运行的任何给定的
Session_Open_Tranactions
事务。Request_Open_Transaction
Session_ID