Mysql 交易不存在';即使其中一个操作失败,也不会失败

Mysql 交易不存在';即使其中一个操作失败,也不会失败,mysql,sql,transactions,commit,acid,Mysql,Sql,Transactions,Commit,Acid,所以我在玩交易,我试着从一个交易中减去资金,然后再转移到另一个交易中。从图中可以看出,第一个更新查询没有成功…与第二个不同,第二个查询执行成功。现在,我所期望的是,当我点击提交时,我不会看到任何变化。但事实并非如此。此外,我还使用了START TRANSACTION(它隐式设置为0),而不是BEGIN命令 以下是此文件的输出: 我错过了什么 我不理解你的困惑。你的两个更新都成功了。第一个不影响任何行,因此只有第二个实际更改了数据 您已提交事务,因此所有更改都将生效 如果要测试事务,请回滚事务。

所以我在玩交易,我试着从一个交易中减去资金,然后再转移到另一个交易中。从图中可以看出,第一个更新查询没有成功…与第二个不同,第二个查询执行成功。现在,我所期望的是,当我点击提交时,我不会看到任何变化。但事实并非如此。此外,我还使用了
START TRANSACTION
(它隐式设置为0),而不是
BEGIN
命令

以下是此文件的输出:


我错过了什么

我不理解你的困惑。你的两个更新都成功了。第一个不影响任何行,因此只有第二个实际更改了数据

您已提交事务,因此所有更改都将生效


如果要测试事务,请回滚事务。然后,当你查看数据时,你会发现没有任何变化。

我不理解你的困惑。你的两个更新都成功了。第一个不影响任何行,因此只有第二个实际更改了数据

您已提交事务,因此所有更改都将生效


如果要测试事务,请回滚事务。然后,当您查看数据时,您将看到没有任何更改。

没有任何操作失败

  • 在第一次更新中,不满足条件,因此没有任何 行已更新
  • 在第二种情况下,一条记录满足条件,因此更新了一条记录

  • 您的任何操作都没有失败

  • 在第一次更新中,不满足条件,因此没有任何 行已更新
  • 在第二种情况下,一条记录满足条件,因此更新了一条记录
  • 作为对存储过程的补充和他对存储过程的提及,我将为未来的读者和完整性添加一个答案,因为我真正的问题是在某些条件不满足时如何回滚事务:

    DELIMITER //
    
    CREATE PROCEDURE transfer(IN sender INT, IN receiver INT)
    
    BEGIN
    
      START TRANSACTION;
    
       SET @senderBalance = (SELECT balance FROM bank_acc WHERE acctnum =  sender LIMIT 1);
       select @senderBalance;
    
        IF (@senderBalance < 50) THEN
          ROLLBACK;
        ELSE
    
        update bank_acc set balance = balance - 50 where acctnum = sender;
        update bank_acc set balance = balance + 50 where acctnum = receiver;
    
          COMMIT;
        END IF;
    END//
    
    
    DELIMITER ;
    作为对存储过程的补充和他对存储过程的提及,我将为未来的读者和完整性添加一个答案,因为我真正的问题是在某些条件不满足时如何回滚事务:

    DELIMITER //
    
    CREATE PROCEDURE transfer(IN sender INT, IN receiver INT)
    
    BEGIN
    
      START TRANSACTION;
    
       SET @senderBalance = (SELECT balance FROM bank_acc WHERE acctnum =  sender LIMIT 1);
       select @senderBalance;
    
        IF (@senderBalance < 50) THEN
          ROLLBACK;
        ELSE
    
        update bank_acc set balance = balance - 50 where acctnum = sender;
        update bank_acc set balance = balance + 50 where acctnum = receiver;
    
          COMMIT;
        END IF;
    END//
    
    
    DELIMITER ;


    第一次查询非常成功,只是没有更新任何记录。@HoneyBadger哦,我明白了。那么,如果这被认为是成功的,那么如果某个特定帐户上没有足够的资金,如何回滚交易?我不明白,您的示例中的两个更新似乎彼此无关,那么,如果第一个更新没有更新任何记录,为什么要回滚?@HoneyBadger它们并不无关。我只是在玩MySQL中的事务,所以一切似乎都有点混乱。不过,它们是相关的。我将资金从一个acc转移到另一个acc。所以,我从弗雷德的acc那里拿了50美元,寄给鲍勃的acc。当然,如果弗雷德的acc没有足够的资金,我想把一切都收回……我认为戈登给了你一个很好的线索。通常,如果出现资金不足的情况,您会希望报告时用红色的大感叹号。这就是为什么我会在应用程序中这样做,而不是让数据库安静地处理它。第一次查询非常成功,只是没有更新任何记录。@HoneyBadger哦,我明白了。那么,如果这被认为是成功的,那么如果某个特定帐户上没有足够的资金,如何回滚交易?我不明白,您的示例中的两个更新似乎彼此无关,那么,如果第一个更新没有更新任何记录,为什么要回滚?@HoneyBadger它们并不无关。我只是在玩MySQL中的事务,所以一切似乎都有点混乱。不过,它们是相关的。我将资金从一个acc转移到另一个acc。所以,我从弗雷德的acc那里拿了50美元,寄给鲍勃的acc。当然,如果弗雷德的acc没有足够的资金,我想把一切都收回……我认为戈登给了你一个很好的线索。通常,如果出现资金不足的情况,您会希望报告时用红色的大感叹号。这就是为什么我会在应用程序中这样做,而不是让数据库安静地处理它。。。我懂了。所以,如果我想限制从一个没有资金的acc中扣除资金,我将不得不接受某种支票约束?我的意思是,如果没有足够的资金,我如何使交易失败?@Whirlwind。编写存储过程并使用
    if
    逻辑。在事务中,检查第一个是否影响任何行。如果不是,则回滚事务。(好吧,没有变化,所以回滚/提交做同样的事情。)@Whirlwind。在MySQL中,检查约束对您没有帮助,因为数据库没有强制执行它们。是的,谢谢。我知道这一点。这就是为什么我说“某种检查约束”。。。我是说在某种替代品上嗯。。。我懂了。所以,如果我想限制从一个没有资金的acc中扣除资金,我将不得不接受某种支票约束?我的意思是,如果没有足够的资金,我如何使交易失败?@Whirlwind。编写存储过程并使用
    if
    逻辑。在事务中,检查第一个是否影响任何行。如果不是,则回滚事务。(好吧,没有变化,所以回滚/提交做同样的事情。)@Whirlwind。在MySQL中,检查约束对您没有帮助,因为数据库没有强制执行它们。是的,谢谢。我知道这一点。这就是为什么我说“某种检查约束”。。。“我的意思是在某种替换上。”GordonLinoff如果你看到什么错误,请随意评论或编辑这篇文章。“但这对我来说很管用。”戈登林诺夫如果你觉得有什么不对劲,请随意评论或编辑这篇文章。但这对我很有效。