2014-04-25 79 views
0

我想尝试交易以及它们如何实际运作。所以我决定编写两个脚本来测试交易的主要功能(处理同时访问数据库)InnoDB交易 - 不起作用

我已经在stackoverflow上问了一个问题,下面是该问题的编辑。但我再次阅读规则,并认为将其发布在我原来的问题下可能是错误的,因为它有些不同。那么请问这个在一个新的问题:

我的代码(和数据库表设置为InnoDB的):

在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(); 
} 

- 方法工作的query。它只是查询字符串。而while环路只为我。我需要一点时间去其他浏览器选项卡中加载使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(); 
} 

随着SELECT我得到了所有的数据库表中的值,这是在第一个空的数组。

现在我打开page1.php,它将在database中插入新数据。但首先它通过循环,大约需要3-4秒。同时,我打开了page2.php

从我的理解,page2.php应该等待page1.php来完成其transaction?但它只是像平常一样加载并输出一个空数组。

当我在page1.php完成加载后刷新page2.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

$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(); 
} 

虽然没有完成page1.php中,第2页应该输出什么都没有,但它输出第70行(取决于我重新加载的速度)

+1

Page 2不等待第1页,否则你可能拥有一些严重的性能问题:它在请求的地方读取数据库,但应该只读取第1页未修改的数据....即,数据库在第1页插入/更新/删除 –

+1

[ACID](http://en.wikipedia.org/wiki/ACID)可能会给你一些关于什么交易都是关于 –

+0

的想法哦,好吧。但我也尝试了另一件事。在第1页上我将500行插入到数据库中,这需要几秒钟的时间。同时,我打开第2页,它确实输出了前70行,这些行正在被第1页添加。但是我不明白为什么。由于'autocommit'被禁用,所以它应该(如你所说)在所有查询完成后才应用这些插入。也许我在我的问题中发布了这段代码。也许有一个错误。 – Quantm

回答

1

事务尝试尽可能避免锁定表/行以提高并发性。这是一件好事。

它们是为了确保一组sql语句全部作为原子单元执行。

这意味着如果发生错误,事务内的所有查询都会回滚。

如何严格/积极的锁定是可以用隔离模式来控制的,在mysql文档中有更多的信息。

所以它听起来像你误解了它的目的,这不是一个信号机制。

+0

很好的答案,但请不要在这里写全部小写。我们有许多编辑提高了问题和答案的质量,我们不希望给他们额外的工作':)'。 – halfer

0

这是交易的预期行为...你所期望的是一种悲观的锁定机制,但是每个关系数据库都使用乐观锁定和事务隔离来加快速度。

您可以在pgsql manual中阅读更多关于此的内容。我知道你的问题是关于mysql的,但它并不重要,因为它是关于并发控制的概念:ACID属性和事务隔离级别等等......