模拟验证一致性非锁定读
2016-05-02 15:56
447 查看
基本信息:
MariaDB [(none)]> select version();
+---------------------+
| version() |
+---------------------+
| 10.0.20-MariaDB-log |
+---------------------+
1 row in set (0.00 sec)
MariaDB [(none)]> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.01 sec)
场景一:在RC级别下验证非一致性锁定读
MariaDB [(none)]> show variables like 'TX_ISOLATION';
+---------------+----------------+
| Variable_name | Value |
+---------------+----------------+
| tx_isolation | READ-COMMITTED |
+---------------+----------------+
1 row in set (0.00 sec)
数据准备:
use lots
create table test (id int,name varchar(20))
engine=innodb DEFAULT CHARSET=utf8;
insert into test values (1,'zeng1'),(2,'zeng2'),(3,'zeng3');
会话一:用begin开启一个事务,查询id=3的记录.
MariaDB [(none)]> use lots;
Database changed
MariaDB [lots]> begin;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lots]> select * from test where id=3;
+------+-------+
| id | name |
+------+-------+
| 3 | zeng3 |
+------+-------+
1 row in set (0.00 sec)
会话二:用begin开启一个事务,并将id=3的记录更改为id=4.
MariaDB [(none)]> use lots;
Database changed
MariaDB [lots]> begin;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lots]> update test set id=4 where id=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
会话一:上面会话二对id=3的记录执行了update操作,还没有commit,有锁定id=3的记录,此时会话一再执行查询id=3的记录,是从最新的快照中查询,返回如下。
MariaDB [lots]> select * from test where id=3;
+------+-------+
| id | name |
+------+-------+
| 3 | zeng3 |
+------+-------+
1 row in set (0.00 sec)
会话二:执行commit
MariaDB [lots]> commit;
Query OK, 0 rows affected (0.00 sec)
会话一:由于会话二已提交,再查询id=3的记录,是从最新快照中查询,所以返回为空。
MariaDB [lots]> select * from test where id=3;
Empty set (0.00 sec)
场景二:在RR级别下验证非一致性锁定读
MariaDB [lots]> set global tx_isolation='Repeatable-Read';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show variables like 'TX_ISOLATION';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
会话一:用begin开启一个事务,查询id=3的记录.
MariaDB [(none)]> use lots;
Database changed
MariaDB [lots]> begin;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lots]> select * from test where id=3;
+------+-------+
| id | name |
+------+-------+
| 3 | zeng3 |
+------+-------+
1 row in set (0.00 sec)
会话二:用begin开启一个事务,并将id=3的记录更改为id=4.
MariaDB [(none)]> use lots;
Database changed
MariaDB [lots]> begin;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lots]> update test set id=4 where id=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
会话一:上面会话二对id=3的记录执行了update操作,还没有commit,有锁定id=3的记录,此时会话一再执行查询id=3的记录,是读取事务开始时快照,返回如下。
MariaDB [lots]> select * from test where id=3;
+------+-------+
| id | name |
+------+-------+
| 3 | zeng3 |
+------+-------+
1 row in set (0.00 sec)
会话二:执行commit
MariaDB [lots]> commit;
Query OK, 0 rows affected (0.00 sec)
会话一:由于会话二已提交,再查询id=3的记录,总是读取事务开始时快照,所以返回结果与上面相同。
MariaDB [lots]> select * from test where id=3;
+------+-------+
| id | name |
+------+-------+
| 3 | zeng3 |
+------+-------+
1 row in set (0.00 sec)
总结:非一致性读锁定,在RR和RC下是不同的,RC读取最新快照数据,RR总是读取事务开始时的快照数据。
MariaDB [(none)]> select version();
+---------------------+
| version() |
+---------------------+
| 10.0.20-MariaDB-log |
+---------------------+
1 row in set (0.00 sec)
MariaDB [(none)]> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.01 sec)
场景一:在RC级别下验证非一致性锁定读
MariaDB [(none)]> show variables like 'TX_ISOLATION';
+---------------+----------------+
| Variable_name | Value |
+---------------+----------------+
| tx_isolation | READ-COMMITTED |
+---------------+----------------+
1 row in set (0.00 sec)
数据准备:
use lots
create table test (id int,name varchar(20))
engine=innodb DEFAULT CHARSET=utf8;
insert into test values (1,'zeng1'),(2,'zeng2'),(3,'zeng3');
会话一:用begin开启一个事务,查询id=3的记录.
MariaDB [(none)]> use lots;
Database changed
MariaDB [lots]> begin;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lots]> select * from test where id=3;
+------+-------+
| id | name |
+------+-------+
| 3 | zeng3 |
+------+-------+
1 row in set (0.00 sec)
会话二:用begin开启一个事务,并将id=3的记录更改为id=4.
MariaDB [(none)]> use lots;
Database changed
MariaDB [lots]> begin;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lots]> update test set id=4 where id=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
会话一:上面会话二对id=3的记录执行了update操作,还没有commit,有锁定id=3的记录,此时会话一再执行查询id=3的记录,是从最新的快照中查询,返回如下。
MariaDB [lots]> select * from test where id=3;
+------+-------+
| id | name |
+------+-------+
| 3 | zeng3 |
+------+-------+
1 row in set (0.00 sec)
会话二:执行commit
MariaDB [lots]> commit;
Query OK, 0 rows affected (0.00 sec)
会话一:由于会话二已提交,再查询id=3的记录,是从最新快照中查询,所以返回为空。
MariaDB [lots]> select * from test where id=3;
Empty set (0.00 sec)
场景二:在RR级别下验证非一致性锁定读
MariaDB [lots]> set global tx_isolation='Repeatable-Read';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show variables like 'TX_ISOLATION';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
会话一:用begin开启一个事务,查询id=3的记录.
MariaDB [(none)]> use lots;
Database changed
MariaDB [lots]> begin;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lots]> select * from test where id=3;
+------+-------+
| id | name |
+------+-------+
| 3 | zeng3 |
+------+-------+
1 row in set (0.00 sec)
会话二:用begin开启一个事务,并将id=3的记录更改为id=4.
MariaDB [(none)]> use lots;
Database changed
MariaDB [lots]> begin;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lots]> update test set id=4 where id=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
会话一:上面会话二对id=3的记录执行了update操作,还没有commit,有锁定id=3的记录,此时会话一再执行查询id=3的记录,是读取事务开始时快照,返回如下。
MariaDB [lots]> select * from test where id=3;
+------+-------+
| id | name |
+------+-------+
| 3 | zeng3 |
+------+-------+
1 row in set (0.00 sec)
会话二:执行commit
MariaDB [lots]> commit;
Query OK, 0 rows affected (0.00 sec)
会话一:由于会话二已提交,再查询id=3的记录,总是读取事务开始时快照,所以返回结果与上面相同。
MariaDB [lots]> select * from test where id=3;
+------+-------+
| id | name |
+------+-------+
| 3 | zeng3 |
+------+-------+
1 row in set (0.00 sec)
总结:非一致性读锁定,在RR和RC下是不同的,RC读取最新快照数据,RR总是读取事务开始时的快照数据。