事务

ACID

A是atomicity,原子性。

C是consistency,一致性。

I是isolation,隔离性。隔离级别很重要,脏读、不可重复读、幻读,都是隔离级别相关的问题。

D是durability,持久性。

下面以mysql数据库详细讲解一下隔离级别。

隔离级别有4种,由低到高,依次为Read Uncommitted、Read Committed、Repeatable read、Serializable。在并发事务的情况下,研究隔离级别才有意义,否则隔离级别没有意义。

Read Uncommitted

读未提交,其实就是一个事务可以读到另一个未提交的事务的操作,这就是脏读问题。

 

Read Committed

读提交。这种隔离级别下没有脏读问题。但是会有所谓的不可重复读,个人认为不可重复读不是一个问题,是理所应当的。

两个事务同时操作一个数据,A事务先读取了一下,B事务修改了这条数据,并提交了。这个时候A再去读,发现数据变了。这种现象就是不可重复读。postgresql、sql server、oracle的默认隔离级别都是Read Committed。

 

Repeatable Read

可重复读。这种隔离级别下可以重复读。两个事务同时操作一个数据,A事务先读取了一下,B事务修改了这条数据,并提交了。这个时候A再去读,读出来的数据和之前一样。

但是会有所谓的幻读问题。幻读指的是,A事务先读取了一下,B事务新增或删除了一条满足A事务查询条件的记录,A事务再去读,发现多或少了一条记录。

mysql的默认隔离级别是Repeatable Read。mysql数据库利用MVCC机制解决了幻读问题,也就是说mysql数据库不会有幻读问题。

实测postgresql数据库在RR级别下也没有幻读问题,在RC模式下有幻读问题。同样的,mysql在RC级别下也有幻读问题。

 

Serializable

这种隔离级别下,事务不能并发,不会有任何问题,但是降低了数据库的性能。

 

不可重复读和幻读的区别

不可重复读的场景是数据有update,幻读的场景是数据有insert或delete。

 

mysql的mvcc机制

mvcc的全称是multiversion concurrency control,中文翻译为多版本并发控制。mvcc通过保存数据快照来实现并发控制。

不加锁的select是快照读。而加锁的select是当前读,比如select ... for update; select ... lock in share mode;当前读,每次读的都是最新数据。

read committed隔离级别时,事务中每次select都会生成一个快照。而repeatable read隔离级别时,只会在事务中第一次select时生成快照。

  

查看系统隔离级别:

select @@global.transaction_isolation;

查看会话隔离级别:

select @@session.transaction_isolation;

设置系统隔离级别:set global transaction isolation level read committed;

修改系统隔离级别后,需要重新建立数据库连接,否则还是会用旧的隔离级别。

设置会话隔离级别:set session transaction isolation level read committed;

 

开启事务:begin;

回滚事务:rollback;

提交事务:commit;

可以查询information_schema库的innodb_trx表来查看进行中的非只读事务。

posted on 2019-07-03 19:45  koushr  阅读(694)  评论(0编辑  收藏  举报

导航