Cra*_*lus 3 mysql perl innodb locking transactions
我认为我对SELECT FOR UPDATE构造感到困惑.
例:
mysql> select * from employees2;
+-------+----------+--------+-----------+
| EmpId | EmpName | DeptId | EmpSalary |
+-------+----------+--------+-----------+
| 1 | John | 1 | 5000.00 |
| 2 | Albert | 1 | 4500.00 |
| 3 | Crain | 2 | 6000.00 |
| 4 | Micheal | 2 | 5000.00 |
| 5 | David | NULL | 34.00 |
| 6 | Kelly | NULL | 457.00 |
| 7 | Rudy | 1 | 879.00 |
| 8 | Smith | 2 | 7878.00 |
| 9 | Karsen | 5 | 878.00 |
| 10 | Stringer | 5 | 345.00 |
| 11 | Cheryl | NULL | NULL |
+-------+----------+--------+-----------+
11 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
我在脚本中执行以下操作:
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
my $dbh = DBI->connect('dbi:mysql:testdb','root','1234', {'RaiseError' => 1, 'AutoCommit' => 0}) or die "Connection Error: $DBI::errstr\n";
my $sql = "select * from employees2 where EmpId IN (2,10) for update";
my $sth = $dbh->prepare($sql);
$sth->execute or die "SQL Error: $DBI::errstr\n";
while (my @row = $sth->fetchrow_array) {
print "@row\n";
}
sleep(9000);
$dbh->commit;
Run Code Online (Sandbox Code Playgroud)
我还并行控制台并连接到数据库.
所以我首先运行脚本,然后在另一个会话中执行:
mysql> select * from employees2 where EmpId IN (10) for update;
Run Code Online (Sandbox Code Playgroud)
第二个选择块指向同一行.
这阻止我做:
mysql> set autocommit = 0;
mysql> begin;
mysql> select * from employees2 where EmpId IN (10) for update;
mysql> commit;
Run Code Online (Sandbox Code Playgroud)
要不就
mysql> select * from employees2 where EmpId IN (10) for update;
Run Code Online (Sandbox Code Playgroud)
因此,如果它在交易中,它就会阻止无关紧要.
现在,如果我将脚本更改为:
my $dbh = DBI->connect('dbi:mysql:practice','root','') or die "Connection Error: $DBI::errstr\n";
Run Code Online (Sandbox Code Playgroud)
即脚本不在事务中运行,第二个会话不会阻塞!
为什么仅在脚本在事务中运行时才会阻塞?