Test of database isolation mechanism under mysql---- 20161022

First, the introduction of database isolation mechanism.

For the concept of database isolation mechanism, you can refer to another article http://simon-9527.iteye.com/blog/2311351 .

First understand what a transaction is

1. Transaction concept: A transaction is a sequence that contains an ordered set of database operation commands, and it is the smallest control unit for concurrent database operations.

2. Transaction characteristics: Atomicity: The database operation commands included in the transaction are either executed or not executed.

Consistency: When a transaction completes, the database is in a stable and consistent state. That is, after the transaction is executed, the database data must comply with the regulations, and the results of all data queries are consistent.

Isolation: When multiple transactions are executed at the same time, they do not interfere with each other.

Persistence: Once a transaction is successfully committed, the changes it causes are permanently preserved, even if hardware and application errors occur.

3. Transaction status:

4. Transaction operation command

         

 

What happens when transactions are executed concurrently?

 

1. Lost updates: When revoking a transaction, overwrite the updated data submitted by other transactions (transactions A and B are executed concurrently, and after transaction A performs the update, commit; transaction B is also done after transaction A is updated and before the end of transaction B The update operation on the row of data is then rolled back, and both update operations are lost).

 

2. Dirty read: A transaction reads the uncommitted update data of another transaction (transactions A and B are executed concurrently, after transaction B executes the update, transaction A queries the uncommitted data of transaction B, and transaction B rolls back, then transaction A gets The data is not the real data in the database . That is, dirty data, that is, data that is inconsistent with the database).


3. Non-repeatable read: A transaction reads the updated data submitted by another transaction (transactions A and B are executed concurrently, transaction A queries the data, then transaction B updates the data, and when A queries the data again, it finds that the data changes ).


4、覆盖更新:这是不可重复读中的特例,一个事务覆盖另一个事务已提交的更新数据(即A事务更新数据,然后B事务更新该数据,A事务查询发现自己更新的数据变了)。

 

5、虚读(幻读):一个事务读到另一个事务已提交的新插入的数据(A和B事务并发执行,A事务查询数据,B事务插入或者删除数据,A事务再次查询发现结果集中有以前没有的数据或者以前有的数据消失了)。

数据库系统提供了四种事务隔离级别供用户选择

1、Serializable(串行化):一个事务在执行过程中完全看不到其他事务对数据库所做的更新(事务执行的时候不允许别的事务并发执行。事务串行化执行,事务只能一个接着一个地执行,而不能并发执行。)。

2、Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他其他事务对已有记录的更新。

3、Read Commited(读已提交数据):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事务已经提交的对已有记录的更新。

4、Read Uncommitted(读未提交数据):一个事务在执行过程中可以看到其他事务没有提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。

 

 

 

 

丢失更新

脏读

非重复读

覆盖更新

幻像读

未提交读

Y

Y

Y

Y

Y

已提交读

N

N

Y

Y

Y

可重复读

N

N

N

N

Y

串行化

N

N

N

N

N

MYSQL默认是什么隔离级别?

    Repeatable read

 

mysql> select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| REPEATABLE-READ        |
+------------------------+
1 row in set (0.00 sec)
 

 

如何查看/修改隔离级别?

    查看:select @@GLOBAL.tx_isolation, @@session.tx_isolation;
    修改:set session transaction isolation level repeatable read;  #repeatable read 可修改成 serializable等

 

mysql> select @@GLOBAL.tx_isolation;
+-----------------------+
| @@GLOBAL.tx_isolation |
+-----------------------+
| REPEATABLE-READ       |
+-----------------------+
1 row in set (0.00 sec)
 

 

二、在mysql中的测试。

1. 建立测试表

 

 CREATE TABLE `test_isolation` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(255) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 2. 直接在本地打开两个mysql命令窗口,其实就应该是两个连接,连个不同的事务,进行测试。

 

第一个窗口直接插入一条数据:

 

mysql> insert into test_isolation (name) values ('simon');
Query OK, 1 row affected (0.03 sec)

mysql> select * from test_isolation;
+----+-------+
| id | name  |
+----+-------+
| 51 | simon |
+----+-------+
1 row in set (0.00 sec)

 

 

第二个窗口查询结果:

 

mysql> select * from test_isolation;
+----+-------+
| id | name  |
+----+-------+
| 51 | simon |
+----+-------+
1 row in set (0.00 sec)

 

 

发现能够查出结果。这并不是说明数据库的隔离机制没有起作用,而是由于mySql数据库的自动提交特性导致的。当采用默认的自动提交时,每一个sql都是一个独立的事务,执行完后直接提交了,这样你在其他的连接或者说事务中也就可以看到提交的结果了。

 

mysql> select * from test_isolation;
+----+-------+
| id | name  |
+----+-------+
| 51 | simon |
+----+-------+
1 row in set (0.00 sec)

 3. 禁止mysql自动提交功能。

(1)可以直接自己手动建立transaction, 通过begin,或者start transaction。

 

 

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

 

 

(2)关掉自动提交功能,session级别的可以直接设置,数据库级别的需要设置配置文件,不过低版本好像不支持,具体可以自己搜索相关的文章。

 

mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> set autocommit=off;
Query OK, 0 rows affected (0.00 sec)

 

 

4. 这时再进行测试

 第一个窗口:

mysql> insert into test_isolation (name) values ('simon');
Query OK, 1 row affected (0.00 sec)

mysql> select * from test_isolation;
+----+-------+
| id | name  |
+----+-------+
| 51 | simon |
| 52 | simon |
+----+-------+
2 rows in set (0.00 sec)

 

 

第二个窗口,这时是看不到第一个事务没有提交的数据的。

mysql> select * from test_isolation;
+----+-------+
| id | name  |
+----+-------+
| 51 | simon |
+----+-------+
1 row in set (0.00 sec)

 

在第一个窗口提交:

mysql> commit;
Query OK, 0 rows affected (0.03 sec)

 

这时第二个窗口的结果,已经可以看到数据。

mysql> select * from test_isolation;
+----+-------+
| id | name  |
+----+-------+
| 51 | simon |
+----+-------+
1 row in set (0.00 sec)

 

The test process for other updates and deletes is similar. You can also set the isolation level of the session and then test it to familiarize yourself with the performance differences of different isolation levels.

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326676005&siteId=291194637