【问题标题】:commit and rollback conflict提交和回滚冲突
【发布时间】:2014-08-20 11:20:39
【问题描述】:

我在 Microsoft SQL Server Management Studio 上执行此查询时遇到了一个问题

CREATE DATABASE myDB
USE myDB

CREATE TABLE udata(uid INT PRIMARY KEY identity(101, 2),
    uname VARCHAR(25), unum INT UNIQUE)

CREATE TABLE usalary(sid INT PRIMARY KEY identity(1, 1),
    salary NUMERIC(18, 0), FKuid INT REFERENCES udata(uid))

INSERT INTO udata VALUES ('yogesh', 99)
INSERT INTO udata VALUES ('tejas',  88)

INSERT INTO usalary VALUES (15000, 103)


BEGIN TRANSACTION
SAVE TRANSACTION SP1
DELETE FROM udata WHERE uid = 1
COMMIT;
ROLLBACK to SP1
SELECT * FROM udata WHERE uid=1

BEGIN TRANSACTION
SAVE TRANSACTION SP2
TRUNCATE TABLE usalary
COMMIT
ROLLBACK to SP2
SELECT * FROM usalary

这里当我们提交事务时,它应该保存在数据库中,但回滚后数据会回来。这怎么可能??

我的问题很简单。 在 SQL 文档中提到,在提交任何查询或事务后,我们无法回滚。(我们无法获得以前的数据库状态。) 就像我们创建保存点 a 并对我们的数据库执行删除查询并显式提交一样。 文档说我们不能从这个状态回滚,但是如果我在这里执行回滚命令,我会取回我的数据。

这里提到了整个命令(查询)系列,以方便希望从创建数据库命令到回滚命令的帮助。

【问题讨论】:

  • “它回来了”是什么意思?您预计会发生什么以及实际上发生了什么?
  • 事务在try catch块中主要是可行的。
  • 这里有些东西没有意义:udata 表的create table 和drop table 没有意义。此外,后面的插入语句假定 udata 表存在。也根本没有提交语句。你期望什么输出,产生什么输出?

标签: sql-server commit rollback


【解决方案1】:

对于这样的查询:

BEGIN TRANSACTION
SAVE TRAN t1
DELETE FROM udata;
COMMIT;
ROLLBACK TRANSACTION t1

您将收到错误消息:The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.。当然,提交后不会回滚。

但如果你尝试将其包装在另一个事务中:

BEGIN TRANSACTION
    BEGIN TRANSACTION
    SAVE TRAN t1
    DELETE FROM udata;
    COMMIT;
    ROLLBACK TRANSACTION t1
COMMIT

这会很好。为什么? documentation on Nesting Transactions 说:

SQL Server 数据库引擎忽略提交内部事务。根据在最外层事务结束时采取的操作,事务要么提交,要么回滚。

我的猜测是:要么您没有在此处发布整个查询,而在其他地方有 BEGIN TRANSACTION 语句,要么您一直在 Management Studio 中测试事务,并且在执行 BEGIN TRANSACTION 的过程中的某处没有匹配 ROLLBACKCOMMIT。在后一种情况下,尝试执行单个ROLLBACK 语句,直到出现错误。您也可以只重新启动 Management Studio。

【讨论】:

    猜你喜欢
    • 2012-08-02
    • 2011-02-25
    • 2013-09-14
    • 1970-01-01
    • 2015-09-12
    • 2016-05-13
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多