简体   繁体   English

InnoDB事务-不起作用

[英]InnoDB transactions - doesn't work

I wanted to try out transactions and how they work practically. 我想尝试交易及其实际运作方式。 So I decided to write two scripts in order to test the main function of transactions (handling simultaneous accesses to the database) 因此,我决定编写两个脚本来测试事务的主要功能(处理对数据库的同时访问)

I already asked a question here on stackOverflow, and the following was an Edit of that question. 我已经在这里在stackOverflow上问过一个问题,以下是对该问题的编辑。 But I read through the rules again and I thought it might be wrong to post it under my original question because it's something different. 但是我再次通读了这些规则,我认为将其发布到我最初的问题下可能是错误的,因为它有所不同。 So I ask this in a new question: 因此,我在一个新问题中提出以下问题:

My Code (and the database table is set to InnoDB): 我的代码(并且数据库表设置为InnoDB):

On page1.php: 在page1.php上:

$db->query("START TRANSACTION;");

$db->query("SET AUTOCOMMIT = 0;");
try {
$i = 0;
while ($i <= 120000000) {
    $i++;
}
var_dump($db->query("INSERT INTO test VALUES (NULL, 'testvalue')"));
$db->query("COMMIT;");
}
catch (Exception $e) {
$db->query("ROLLBACK;");
echo $e->getMessage();
}

the query -method works. query方法有效。 It just queries the string. 它只是查询字符串。 And the while -loop is just for me. while循环只适合我。 I need a bit time to go to the other browser tab to load page2.php: 我需要一点时间转到另一个浏览器选项卡来加载page2.php:

$db->query("START TRANSACTION;");
$db->query("SET AUTOCOMMIT = 0;");
try {
    // outputs an array with the data
    var_dump($db->query("SELECT * FROM test", "assoc"));
    $db->query("COMMIT;");
}
catch (Exception $e) {
    $db->query("ROLLBACK");
    echo $e->getMessage();
}

With the SELECT I get an array with all of the values inside the database table, which was empty at first. 通过SELECT我得到了一个包含数据库表中所有值的数组,该表最初是空的。

Now I opened page1.php which will insert new data into the database . 现在我打开page1.php,它将新数据插入database But first it runs through the loop, which takes about 3-4 seconds. 但首先,它会运行整个循环,大约需要3-4秒。 Meanwhile, I open up page2.php . 同时,我打开page2.php

From my understanding, page2.php should have waited for page1.php to complete its transaction ?? 据我了解,page2.php应该已经等待page1.php完成其transaction But it just loads as usual and outputs an empty Array. 但是它只是照常加载,并输出一个空数组。

When I refresh page2.php after page1.php finished loading, I get the correct output with the new data. 当page1.php完成加载后刷新page2.php ,我得到了包含新数据的正确输出。

Where is my mistake? 我的错误在哪里? I don't quite understand it. 我不太明白。

EDIT: Here is another one I tried: 编辑:这是我尝试过的另一个:

page1.php page1.php中

$db->query("SET AUTOCOMMIT = 0;");
$db->query("START TRANSACTION;");
try {

    //print_r($db->query("DELETE FROM test;", "affected"));
    $i = 200;
    while ($i <= 700) {
        var_dump($db->query("INSERT INTO test VALUES ({$i}, 'testvaluetestvaluetestvaluetestvaluetestvalue')"));
        $i++;
    }

    $db->query("COMMIT;");
}
catch (Exception $e) {
    $db->query("ROLLBACK;");
    echo $e->getMessage();
}

page2.php 使page2.php

$db->query("SET AUTOCOMMIT = 0;");
$db->query("START TRANSACTION;");

try {
    var_dump($db->query("SELECT * FROM test", "assoc"));
    $db->query("COMMIT;");
}
catch (Exception $e) {
    $db->query("ROLLBACK");
    echo $e->getMessage();
}

While page1.php is not completed, page 2 should output nothing , but it outputs the first 70 rows (depending on how fast I reloaded) 虽然page1.php未完成,但第2页应该什么也不输出,但是它输出前70行(取决于我重新加载的速度)

transactions try to avoid locking tables / rows wherever possible to improve concurrency. 事务尽量避免锁定表/行,以提高并发性。 that is a good thing. 这是一件好事。

what they are for is to ensure that a set of sql statements all execute as an atomic unit. 它们的作用是确保一组sql语句全部作为原子单元执行。

meaning if an error occurs all the queries within the transaction are rolled back. 表示如果发生错误,则回滚事务中的所有查询。

how strict / aggressive the locking is can be controlled with isolation modes, more infos in the mysql documentation. 可以使用隔离模式控制锁定的严格/严格程度,有关更多信息,请参见mysql文档。

so it sounds like you are misunderstanding theire purpose, the are not a semaphore mechanism. 因此听起来您误解了他们的目的,这不是信号量机制。

This is the expected behavior by transactions... What you expected is a pessimistic locking mechanism, but every relational database uses optimistic locking and transaction isolation to make thing faster. 这是事务的预期行为...您期望的是悲观锁定机制,但是每个关系数据库都使用乐观锁定和事务隔离来使事情更快。

You can read more about this in the pgsql manual . 您可以在pgsql手册中阅读更多有关此的内容。 I know your question is about mysql, but it does not really matter, because it's about concurrency control conceptions: ACID properties and transaction isolation levels, etc... 我知道您的问题是关于mysql的,但这并不重要,因为它是关于并发控制概念的:ACID属性和事务隔离级别等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM