如果不向数据库(比如 SQLServer)提交事务,会发生什么情况?

假设我有一个疑问:

begin tran
-- some other sql code

然后我就会忘记承诺或者回滚。

如果另一个客户机尝试执行查询,会发生什么情况?

166837 次浏览

取决于传入事务的隔离级别。

Sql 事务隔离解释道

事务的目的是要么完全运行,要么根本不运行。完成事务的唯一方法是提交,任何其他方法都将导致回滚。

因此,如果您先开始,然后又不提交,那么它将在连接关闭时回滚(因为事务被中断而没有标记为完成)。

只要你没有 承诺后退事务,它仍然“运行”,并可能持有锁。

如果您的客户端(应用程序或用户)在提交之前关闭到数据库的连接,则任何仍在运行的事务都将回滚并终止。

当您打开一个事务时,没有任何东西会自己被锁定。但是,如果您在该事务中执行某些查询,根据隔离级别的不同,一些行、表或页将被锁定,因此将影响试图从其他事务访问它们的其他查询。

你可以自己尝试一下这个,这会帮助你了解它是如何工作的。

在管理工作室中打开两个窗口(选项卡) ,每个窗口都有自己到 sql 的连接。

现在您可以在一个窗口中开始一个事务,执行一些诸如插入/更新/删除之类的操作,但尚未提交。然后在另一个窗口中,您可以看到数据库在事务外的外观。根据隔离级别的不同,表可能被锁定,直到第一个窗口被提交,或者您可能(没有)看到其他事务到目前为止做了什么,等等。

尝试使用不同的隔离级别,并且不使用锁提示来查看它们如何影响结果。

还可以看到在事务中抛出错误时会发生什么。

了解所有这些东西是如何工作的非常重要,否则您将会被 sql 的工作难倒,很多时候。

玩得开心! GJ。

除了可能导致的锁定问题,你还会发现事务日志开始增长,因为它们不能被截断超过活动事务的最小 LSN,如果你使用快照隔离,你的 temdb 版本存储也会因为类似的原因而增长。

您可以使用 dbcc opentran查看最早打开的事务的详细信息。

没有定义行为,因此必须显式设置提交或回滚:

Http://docs.oracle.com/cd/b10500_01/java.920/a96654/basic.htm#1003303

”如果自动提交模式被禁用,并且您在没有显式提交或回滚上次更改的情况下关闭了连接,那么将执行一个隐式 COMMIT 操作

Hsqldb 进行了回滚

con.setAutoCommit(false);
stmt.executeUpdate("insert into USER values ('" +  insertedUserId + "','Anton','Alaf')");
con.close();

结果是

2011-11-1414:20:22,519 main INFO [ SqlAutoCommit example: 55][ AutoCommit enable = false ] 2011-11-1414:20:22,546 main INFO [ SqlAutoCommittee example: 65][ Found 0 # users in database ]2011-11-1414:20:22,546主要信息[ SqlAutoCommit 示例: 65][在数据库中找到0 # 用户]

事务示例

开始传送

您的 sql 语句

如果发生错误 回滚传输 别的 交出来

只要您没有执行提交 tran tt,数据就不会被更改

任何未提交的事务都会锁定服务器,其他查询不会在服务器上执行。您要么需要回滚事务,要么需要提交事务。关闭 SSMS 也将终止允许执行其他查询的事务。

我真的忘记提交一个交易。我有一个查询,如下面的代码。

调用此存储过程的方法是。网。中测试函数时。NET 应用程序中捕获异常。净申请。

例外信息如下:

EXECUTE 之后的事务计数表明 BEGIN 和 COMMIT 语句的数目不匹配。上次计数 = 0,当前计数 = 1。

当我意识到这个错误时,我已经尝试了很多次,两次都是在。Net 应用程序和 SQLServerManagementStudio (2018)。(在 SSMS 中,output 语句将成功地在 Results选项卡中输出结果,但在 Messages选项卡中显示错误消息。)

然后我发现这个事务中使用的表被锁定了。当我只选择 top 1000而不选择 order desc时,它可以选择结果。但是当我用 order desc选择 top 1000时,它会运行很长一段时间。

当我关闭.Net 应用程序时,事务未被提交(基于事务中未更改的数据)。

当我关闭 EXEC ...选项卡(执行伪造的提交查询)时,SSMS 将弹出一个警告窗口:

有未提交的事务。要提交这些事务吗?

我已经测试了 YesNo的选择。

如果我单击 Yes,事务就被提交。

如果我单击 No,事务就不会提交。

关闭选项卡后,锁定的表将被释放,然后我就可以成功地查询了。

begin try
-- some process
begin transaction
update ...
output ...
    



insert ...


-- I missing this commit statement below
commit transaction
end try
begin catch
if (xact_state()) = -1
begin
rollback transaction;
;throw
end;


-- this statement I want to compare to 1, but mistake write to -1, but since the throw statement let the mistake can't be triggerd
if (xact_state()) = 1
begin
commit transaction;
end;
end catch;