【问题标题】:Mysql transaction : commit and rollbackMysql事务:提交和回滚
【发布时间】:2013-11-22 08:18:54
【问题描述】:

我将我的 PhpMyAdmin 数据库引擎从 MyISAM 更新为 INNODB 以允许回滚。

这是我的 SQL 查询:

START TRANSACTION;
UPDATE jkm_content SET state=0 WHERE title IN ('title-1','title2');

结果:

start transaction;# MySQL returned an empty result set (i.e. zero
rows).
UPDATE jkm_content SET state=1 WHERE title IN ('title-1','title2');# 2 rows affected.

1) 所以该语句通知我有 2 行受到影响,但更改没有出现在任何地方(在我的数据库和网站中都没有)。我虽然 start transaction 可以让我可视化更改(暂时DB)然后如果我满意我“提交”查询。 (我知道我需要commit 来更新数据库,但如果我commit 更改将是永久性的)。

2) 那我不明白rollback的意思,如果我在提交之前看不到效果。这两个查询有什么区别:

START TRANSACTION;
UPDATE jkm_content SET state=0 WHERE title IN ('title-1','title2');

START TRANSACTION;
UPDATE jkm_content SET state=0 WHERE title IN ('title-1','title2');
ROLLBACK;

3) 如果我没记错的话,这些功能都是一样的:

START TRANSACTION
BEGIN
BEGIN WORK

【问题讨论】:

    标签: php mysql sql transactions rollback


    【解决方案1】:

    1) 您所做的所有更改都在同一事务中可见。如果你这样做了

    START TRANSACTION;
    INSERT INTO MyTable VALUES ('Hi there');
    SELECT * FROM MyTable;
    

    您的输出将包括“您好”。但是,如果您启动第二个数据库连接,则在您从第一个连接中提交事务之前,不会显示新行。尝试使用命令行使用两个数据库连接来玩这个。

    您没有在您的网站中看到效果,因为您不能在两个数据库连接中进行相同的事务(将在您的请求开始时建立一个新的数据库连接)。

    2) 当与数据库的连接关闭时,所有未提交的事务将被回滚。因此,如果这些是您仅有的两个查询,则没有区别。不过还是有区别的

    START TRANSACTION;
    INSERT INTO MyTable VALUES ('This one would be discarded on rollback');
    ROLLBACK;
    INSERT INTO MyTable VALUES ('This one will be permanent because not within transaction');  
    

    3) 是的,这些都是一样的。

    【讨论】:

    • 感谢您的帮助!
    【解决方案2】:
    1. 在事务提交之前,您在一个事务中所做的更改对其他事务(具有READ UNCOMMITTED 隔离级别的事务除外)不可见。

    2. 回滚事务和保持它永远打开(或者直到引擎由于超时而终止它)之间存在巨大差异。后者意味着服务器无法释放分配给支持事务的资源。另外,由于你做了UPDATE,mysql 必须对受影响的行发出排他锁,并且没有其他事务可以更新/删除这些行。如果您的应用程序使事务处于打开状态,那么您很可能最终会导致所有连接都忙并永远等待,或者出现一堆死锁。

    3. 是的,它们都在mysql中启动了一个新事务。

    【讨论】:

    • 感谢您的回答。我将始终以回滚结束我的查询!
    猜你喜欢
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-20
    • 1970-01-01
    • 2012-05-22
    • 2019-05-29
    • 2011-10-01
    相关资源
    最近更新 更多