Mysql的隔离级别和事务

1.1. 事务的特性

1.1. 事务语法

 

1.1.1. 开启事务

1begin

2START TRANSACTION(推荐)

3begin work

 

1.1.2. 事务回滚  

rollback

 

1.1.3. 事务提交

  commit

 

1.1.4. 还原点

savepoint

show variables like '%autocommit%';  自动提交事务是开启的

 

set autocommit=0;

 

insert into testdemo values(5,5,5);

savepoint s1;

insert into testdemo values(6,6,6);

savepoint s2;

insert into testdemo values(7,7,7);

savepoint s3;

 

 

 

select * from testdemo

rollback to savepoint s2

 

rollback

1.2 事务隔离级别

mysql默认的事务隔离级别为repeatable-read

show variables like '%tx_isolation%';

1.1.1. 未提交读(READ UNCOMMITED)脏读

set SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

测试:

启动两个session

一个session

  start TRANSACTION

  update account set balance = balance -50 where id = 1

另外一个session中查询

select * from account

回到第一个session中 回滚事务

ROLLBACK

在第二个session

update account set balance = balance -50 where id = 1

查询结果还是 400

第二个session以为结果是350,但前面的400数据为脏读数据,导致最后的结果和意料中的结果并不一致。

1.1.2. 已提交读 READ COMMITED)不可重复读

测试

show variables like '%tx_isolation%';

set SESSION TRANSACTION ISOLATION LEVEL read committed;

一个session

  start TRANSACTION

  update account set balance = balance -50 where id = 1

另外一个session中查询 (数据并没改变)

select * from account

回到第一个session中 回滚事务

commit

在第二个session

select * from account (数据已经改变)

1.1.3. 可重复读(REPEATABLE READ

测试

show variables like '%tx_isolation%';

set SESSION TRANSACTION ISOLATION LEVEL repeatable read;

一个session

  start TRANSACTION

  update account set balance = balance -50 where id = 1

另外一个session中查询 (数据并没改变)

select * from account

 

回到第一个session中 回滚事务

commit

在第二个session

select * from account (数据并未改变)

1.1.4. 可串行化(SERIALIZABLE

account 表有3条记录,业务规定,最多允许4条记录。

1.开启一个事务

begin

select * from account  发现3条记录

2.开启另外一个事务

begin

select * from account  发现3条记录 也是3条记录

insert into account VALUES(4,'deer',500)

查询  4条记录

select * from account

3.回到第一个session

insert into account VALUES(5,'james',500)

select * from account  4条记录

4.session1 session2 都提交事务 

set SESSION TRANSACTION ISOLATION LEVEL serializable; 重新上面的测试发现插入报错

 

1.1.1. 总结

       事务隔离级别为可重复读时,如果有索引(包括主键索引)的时候,以索引列为条件更新数据(是在行上加锁的情况 -- for update),会存在间隙锁间、行锁、页锁的问题,从而锁住一些行;如果没有索引,更新数据时会锁住整张表

       事务隔离级别为串行化时,读写数据都会锁住整张表

       隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大,对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。

 

posted @ 2019-07-13 20:00  宥宥美美  阅读(251)  评论(0编辑  收藏  举报