如果您不向数据库(例如 SQL Server)提交事务,会发生啥情况?
Posted
技术标签:
【中文标题】如果您不向数据库(例如 SQL Server)提交事务,会发生啥情况?【英文标题】:What happens if you don't commit a transaction to a database (say, SQL Server)?如果您不向数据库(例如 SQL Server)提交事务,会发生什么情况? 【发布时间】:2011-06-21 06:07:31 【问题描述】:假设我有一个查询:
begin tran
-- some other sql code
然后我忘记提交或回滚。
如果另一个客户端尝试执行查询,会发生什么?
【问题讨论】:
【参考方案1】:只要您不COMMIT 或ROLLBACK 事务,它仍然“运行”并可能持有锁。
如果您的客户端(应用程序或用户)在提交之前关闭与数据库的连接,则任何仍在运行的事务都将回滚并终止。
【讨论】:
嗯,好吧,我发现这是在创建某种锁。我不确定关闭连接是否真的会让我摆脱这种状态。问题是我在尝试提交时遇到了错误。现在我关闭了连接,一切正常。 旁注:如果使用 Management Studio,关闭查询窗口将关闭连接 @BradleyDotNET:是的,当然 请记住,默认情况下,如果您关闭查询窗口/连接,SQL Server Management Studio 会自动提交。 每个人都应该注意这个回复中“可能持有锁”的部分。【参考方案2】:任何未提交的事务都会使服务器处于锁定状态,并且其他查询不会在服务器上执行。您要么需要回滚事务,要么提交它。关闭 SSMS 也将终止允许其他查询执行的事务。
【讨论】:
【参考方案3】:您实际上可以自己尝试一下,这应该有助于您了解其工作原理。
在 management studio 中打开两个窗口(选项卡),每个窗口都有自己的 sql 连接。
现在您可以在一个窗口中开始事务,执行插入/更新/删除等操作,但尚未提交。然后在另一个窗口中,您可以从事务外部查看数据库的外观。根据隔离级别,表可能会被锁定直到第一个窗口被提交,或者您可能(不)看到其他事务到目前为止所做的事情,等等。
使用不同的隔离级别和没有锁定提示来查看它们如何影响结果。
还可以查看在事务中抛出错误时会发生什么。
了解所有这些东西是如何工作的非常重要,否则您将多次被 sql 的功能所困扰。
玩得开心! GJ。
【讨论】:
好的,但至少在发出提交之前,事务是否会被写入日志?例如,假设我想启动一个事务,在执行提交之前运行一个插入命令并“做其他事情”。我的插入命令会被写入日志吗?这样,如果服务器在执行提交之前崩溃..它可以回到原来的位置,我可以稍后发出提交(每当我完成“其他事情”时)。 @user1870400 很明显,这个用户给出的答案是……试试看。【参考方案4】:交易示例
开始传输 tt
你的 sql 语句
如果发生错误 回滚传输 别的 提交传输 tt
只要你没有执行 commit tran tt ,数据就不会改变
【讨论】:
请注意,命名事务不仅在 MS SQL 中是不必要的,还会给人一种错误的控制感。例如,BEGIN TRAN X ... BEGIN TRAN Y ... ROLLBACK Y
不起作用。见***.com/questions/1273376/…【参考方案5】:
行为未定义,因此您必须显式设置提交或回滚:
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# 个用户]
【讨论】:
这对 Oracle 来说可能是真的(我不知道),但提问者询问的是 MS-SQL 第一个引号适用于 JDBC 驱动程序,而不适用于服务器。【参考方案6】:除了可能导致的潜在锁定问题之外,您还会发现事务日志开始增长,因为它们不能被截断超过活动事务的最小 LSN,并且如果您使用快照隔离,则您的版本存储在 tempdb会因为类似的原因而增长。
您可以使用dbcc opentran
查看最早的未结交易的详细信息。
【讨论】:
【参考方案7】:当您打开交易时,没有任何东西会自行锁定。但是,如果您在该事务中执行某些查询,根据隔离级别,某些行、表或页面会被锁定,因此会影响尝试从其他事务访问它们的其他查询。
【讨论】:
【参考方案8】:事务旨在完全运行或根本不运行。完成事务的唯一方法是提交,任何其他方式都会导致回滚。
因此,如果您开始然后不提交,它将在连接关闭时回滚(因为事务被中断而没有标记为完成)。
【讨论】:
本应如此,但并非总是如此。 ...比如 mysql 的 MyISAM,它确实不支持事务。【参考方案9】:取决于传入事务的隔离级别。
Sql transaction isolation explained
【讨论】:
事务的行为不依赖于隔离级别。它们可能导致的锁定数量确实如此。 我很确定连接能够读取哪些数据绝对取决于隔离级别。如果您将隔离设置为 READ UNCOMMITTED,您可以读取尚未提交的数据,并且实际上可能会在某个时间点回滚轨道,但这可以确保没有锁定。如果您将 READ COMMITTED 作为您的隔离级别,那么您将无法读取未提交的行 - 除非您使用 SNAPSHOT,否则第二个客户端将挂起。以上是关于如果您不向数据库(例如 SQL Server)提交事务,会发生啥情况?的主要内容,如果未能解决你的问题,请参考以下文章
HTML 表单和 PHP 脚本 - 不向 MySQL 数据库表提交数据