假设我有一个查询:
begin tran
-- some other sql code
然后我忘记提交或回滚。
如果另一个客户端尝试执行查询,会发生什么?
假设我有一个查询:
begin tran
-- some other sql code
然后我忘记提交或回滚。
如果另一个客户端尝试执行查询,会发生什么?
你可以亲自尝试一下,这会帮助你更加了解它是如何工作的。
在管理工具中打开两个窗口(标签),每一个窗口都有自己连接到 SQL 的方式。
现在,在一个窗口中开始一个事务,并执行一些操作,比如插入/更新/删除,但还没有提交。然后,在另一个窗口中,您可以查看从事务外部看数据库的情况。根据隔离级别,直到第一个窗口提交之前,表可能会被锁定,或者你可能(不)看到其他事务已经做了什么等等。
尝试使用不同的隔离级别和无锁提示来看看它们如何影响结果。
还要看看在事务中发生错误时会发生什么。
非常重要的是要理解所有这些东西是如何工作的,否则您会经常被 SQL 所困扰。
玩得开心!GJ。
事务旨在完全运行或不运行。 完成交易的唯一方法是提交,任何其他方式都将导致回滚。
因此,如果您开始但未提交,则在连接关闭时它将被回滚(因为事务已被中断而没有标记为完成)。
当您打开一个事务时,它本身并不会被锁定。但是,如果在该事务中执行一些查询,根据隔离级别,某些行、表或页面将被锁定,因此将影响其他事务尝试从中访问它们的查询。
事务示例
开始事务 tt
您的 SQL 语句
如果发生错误,则回滚事务 tt;否则,提交事务 tt。
只要未执行 commit tran tt,数据就不会被更改。
dbcc opentran
查看最旧的打开事务的详细信息。我真的忘记提交事务了。我有一个像下面代码一样的查询。
这个存储过程是由.Net调用的。当我在.Net应用程序中测试函数时,异常将被捕获在.Net应用程序中。
异常消息如下:
执行后的事务计数表明BEGIN和COMMIT语句不匹配。之前的计数=0,当前的计数=1。
当我意识到错误时,我尝试了很多次,在.Net应用程序和SQL Server Management Studio(2018)中都尝试了。(在SSMS中,输出语句将在“结果”选项卡中成功输出结果,但在“消息”选项卡中显示错误消息。)
然后我发现在此事务中使用的表被锁定了。当我只选择前1000个而没有使用order desc
时,它可以选择结果。但是当我选择前1000个并使用order desc
时,它将运行很长时间。
当我关闭.Net应用程序时,事务未提交(基于事务中未更改的数据)。
当我关闭执行伪造提交查询的EXEC ...
选项卡时,SSMS将弹出一个警告窗口:
有未提交的事务。您是否要提交这些事务?
我已经测试了是
和否
两个选项。
如果我点击是
,那么这些事务将被提交。
如果我点击否
,那么这些事务将不会被提交。
在关闭选项卡后,我的锁定表将被释放,然后我就可以成功查询。
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;
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-14 14:20:22,519 主要的 信息 [SqlAutoCommitExample:55] [自动提交已启用 = false] 2011-11-14 14:20:22,546 主要的 信息 [SqlAutoCommitExample:65] [在数据库中找到0#用户]