begin tran
update titles set price=70 where title_id='tc7777'
begin tran
update titles set type='csdn' where title_id='tc7777'
rollback tran
commit tran这样就只回滚
update titles set type='csdn' where title_id='tc7777'

解决方案 »

  1.   

    是嵌套的两个事务而且,可是已经COMMIT 是不能在回滚的啊 为什么又回滚到初始状态了呢?
      

  2.   

    嵌套事务
    显式事务可以嵌套。这主要是为了支持存储过程中的一些事务,这些事务可以从事务中已有的进程中调用,也可以从没有活动事务的进程中调用。下面的示例显示了嵌套事务的用途。TransProc 过程强制执行其事务,而不管执行该事务的进程的事务模式如何。如果在事务活动时调用 TransProc,则 TransProc 中的嵌套事务几乎被忽略,而且其 INSERT 语句将根据对外部事务采取的最终操作提交或回滚。如果不含有未完成事务的进程执行 TransProc,则在该过程结束时,COMMIT TRANSACTION 将有效地提交 INSERT 语句。SET QUOTED_IDENTIFIER OFF
    GO
    SET NOCOUNT OFF
    GO
    USE pubs
    GO
    CREATE TABLE TestTrans(Cola INT PRIMARY KEY,
                   Colb CHAR(3) NOT NULL)
    GO
    CREATE PROCEDURE TransProc @PriKey INT, @CharCol CHAR(3) AS
    BEGIN TRANSACTION InProc
    INSERT INTO TestTrans VALUES (@PriKey, @CharCol)
    INSERT INTO TestTrans VALUES (@PriKey + 1, @CharCol)
    COMMIT TRANSACTION InProc
    GO
    /* Start a transaction and execute TransProc */
    BEGIN TRANSACTION OutOfProc
    GO
    EXEC TransProc 1, 'aaa'
    GO
    /* Roll back the outer transaction, this will
       roll back TransProc's nested transaction */
    ROLLBACK TRANSACTION OutOfProc
    GO
    EXECUTE TransProc 3,'bbb'
    GO
    /* The following SELECT statement shows only rows 3 and 4 are 
       still in the table. This indicates that the commit
       of the inner transaction from the first EXECUTE statement of
       TransProc was overridden by the subsequent rollback. */
    SELECT * FROM TestTrans
    GOMicrosoft® SQL Server™ 忽略提交内部事务。根据最外部事务结束时采取的操作,将提交或者回滚事务。如果提交外部事务,则内层嵌套的事务也会提交。如果回滚外部事务,则不论此前是否单独提交过内层事务,所有内层事务都将回滚。对 COMMIT TRANSACTION 或 COMMIT WORK 的每个调用都应用于最后执行的 BEGIN TRANSACTION。如果嵌套 BEGIN TRANSACTION 语句,那么 COMMIT 语句只应用于最后一个嵌套的事务,也就是在最内层的事务。即使嵌套事务内部的 COMMIT TRANSACTION transaction_name 语句引用外部事务的事务名,该提交也只应用于最内层的事务。ROLLBACK TRANSACTION 语句的 transaction_name 参数引用一组命名的嵌套事务的内层事务是非法的,transaction_name 只能引用最外部事务的事务名。如果在一组嵌套事务的任意级别执行使用外部事务名称的 ROLLBACK TRANSACTION transaction_name 语句,那么所有的嵌套事务都将回滚。如果在一组嵌套事务的任意级别执行没有 transaction_name 参数的 ROLLBACK WORK 或 ROLLBACK TRANSACTION 语句,那么它将回滚所有嵌套事务,包括最外部事务。@@TRANCOUNT 函数记录当前事务的嵌套级。每个 BEGIN TRANSACTION 语句使 @@TRANCOUNT 加 1。每个 COMMIT TRANSACTION 或 COMMIT WORK 语句使 @@TRANCOUNT 减 1。没有事务名的 ROLLBACK WORK 或 ROLLBACK TRANSACTION 语句将回滚所有嵌套事务,并使 @@TRANCOUNT 减小到 0。使用一组嵌套事务中最外部事务的事务名称的 ROLLBACK TRANSACTION 将回滚所有嵌套事务,并使 @@TRANCOUNT 减到 0。在无法确定是否已经在事务中时,可以用 SELECT @@TRANCOUNT 语句确定 @@TRANCOUNT 是 1 还是更大。如果 @@TRANCOUNT 是 0,则表明不在事务中。
      

  3.   

    begin tran
    update titles set price=70 where title_id='tc7777'
    begin tran
    update titles set type='csdn' where title_id='tc7777'
    commit tran
    rollback tranbegin tran
    update titles set price=70 where title_id='tc7777'
    begin tran
    update titles set type='csdn' where title_id='tc7777'
    commit tran
    rollback tranbegin tran
    update titles set price=70 where title_id='tc7777'
    begin tran
    update titles set type='csdn' where title_id='tc7777'
    commit tran
    rollback tran你看看他的结果是什么?
      

  4.   

    上面的语句应该是这样
    begin tran
    update titles set price=70 where title_id='tc7777'
    begin tran
    update titles set type='csdn' where title_id='tc7777'
    commit tran
    rollback tranbegin tran
    update titles set price=70 where title_id='tc7777'
    begin tran
    update titles set type='csdn' where title_id='tc7777'
    commit tran
    --rollback tranbegin tran
    update titles set price=70 where title_id='tc7777'
    begin tran
    update titles set type='csdn' where title_id='tc7777'
    commit tran
    rollback tran
    其实你执行3次,也就是执行了上面的1次
    而这是6个级别的嵌套事务,需要6次commit tran才能真正的提交,而你的事物是在没有被完全提交的时候就被ROLLBACK了
    ROLLBACK TRANSACTION 将清除自事务的起点或到某个保存点所做的所有数据修改