mysql> SELECT @@session.tx_isolation; +------------------------+ | @@session.tx_isolation | +------------------------+ | REPEATABLE-READ | +------------------------+ 1 row in set
mysql> in^sert into test(name) values("a"); Query OK, 1 row affected
mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | a | +----+------+ 1 row in set
mysql> SELECT @@session.tx_isolation; +------------------------+ | @@session.tx_isolation | +------------------------+ | REPEATABLE-READ | +------------------------+ 1 row in set
mysql> start transaction; Query OK, 0 rows affected
mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | a | +----+------+ 1 row in set
准备数据,插入一条数据。
mysql> start transaction; Query OK, 0 rows affected
mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | a | +----+------+ 1 row in set 事务A只看到一条数据。 mysql> in^sert into test(name) values("b "); Query OK, 1 row affected mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | a | +----+------+ 1 row in set 事务A还是只看到一条数据。 mysql> up^date test set name="aaa" where id=1; Query OK, 1 row affected Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test where id=1; +----+------+ | id | name | +----+------+ | 1 | a | +----+------+ 1 row in set 事务A的数据还是没有变,哈哈。
mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | aaa | | 2 | b | +----+------+ 2 rows in set 事务B的数据已经变了
mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | a | +----+------+ 1 row in set 事务A的数据还是这样,看不到事务B的数据变化,很正常。
mysql> commit; Query OK, 0 rows affected
mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | aaa | | 2 | b | +----+------+ 2 rows in set 事务B提交了,生效了,一切正常。
mysql> up^date test set name="bbb" where id=2 ; Query OK, 1 row affected Rows matched: 1 Changed: 1 Warnings: 0 事务A按id更新第二条数据,竟然更新成功了,哈~~
mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | a | | 2 | bbb | +----+------+ 2 rows in set 然后第二条数据就看到了,好神奇~~
mysql> commit; Query OK, 0 rows affected 事务A也提交
mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | aaa | | 2 | bbb | +----+------+ 2 rows in set
mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | aaa | | 2 | bbb | +----+------+ 2 rows in set
第二条数据也变了。 ------------------------------------------------------ 结论: REPEATABLE-READ级别下: select都是快照,不会上锁, 其他事务可以进行in^sert,up^date,delete操作 只是,其他事务in^sert,这边看不到,指的是select看不到。 up^date这边看不到,指的是select看不到。 delete这边还是无影响,记录依然存在,指的是select看不到。 因为select的是事务开始时的快照。
但是这边up^date的话,会发现那条记录。----这个应该就是幻读吧。select看不到数据,up^date却看到了~。 也就是说,up^date是真实去操作数据了。 它是找到那个数据,上锁,然后更新…… 但是不提交的话,其他事务是看不到的。 (怎么做到的?给真实数据上锁,做的修改在一个虚拟空间里?commit时再修改真实数据?)
|