Springboot设置事务隔离等级:
1、@EnableTransactionManagement 来启用注解式事务管理
2、@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)设置事务隔离级别和传播行为
这两篇文章可以结合起来一起理解:
面试官:谈谈你对Mysql的MVCC的理解?
这一篇我觉得是写MVCC写的最好的一篇:
Innodb中的事务隔离级别和锁以及MVCC之间的关系
MVCC的意义只是替代读锁,写依旧是加锁的,这样避免了脏写
MVCC不可以避免幻读。(但是有的文章说mvcc防住了幻读,没防住是因为把快照读提升到了当前读的模式)
如果要避免幻读,可以使用MVCC+间隙锁的方式。
MySQL 到底是怎么解决幻读的?
快照(ReadView)读的幻读-mvcc 解决
当前读的幻读-Next-Key锁解决
当前读与快照读:
首先读分为:
快照读
select * from table where ?;
当前读:特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。
select * from table where ? lock in share mode;
select * from table where ? for update;
insert into table values (…);
update table set ? where ?;
delete from table where ?;
对于快照读来说,幻读的解决是依赖mvcc解决。而对于当前读则依赖于Next-Key锁解决。
MySQL事务隔离级别和实现原理(看这一篇文章就够了!):
MySQL 中是如何实现事务隔离的:
并发写的时候加锁问题:
加锁的过程要分有索引和无索引两种情况,比如下面这条语句
update user set age=11 where id = 1
id 是这张表的主键,是有索引的情况,那么 MySQL 直接就在索引数中找到了这行数据,然后干净利落的加上行锁就可以了。
而下面这条语句
update user set age=11 where age=10
表中并没有为 age 字段设置索引,所以, MySQL 无法直接定位到这行数据。那怎么办呢,当然也不是加表锁了。MySQL 会为这张表中所有行加行锁,没错,是所有行。但是呢,在加上行锁后,MySQL 会进行一遍过滤,发现不满足的行就释放锁,最终只留下符合条件的行。虽然最终只为符合条件的行加了锁,但是这一锁一释放的过程对性能也是影响极大的。所以,如果是大表的话,建议合理设计索引,如果真的出现这种情况,那很难保证并发度。
mysql在RR隔离级别下有MVCC,那还有共享锁吗?
回答一:对于具备多版本控制能力的数据库引擎确实不需要对表的读取加锁, MVCC能保障读取的完整性. MVCC 仅于单行(或单个字段)起作用, 锁可以实现多行多表多操作的事务锁定. 锁用途和 MVCC 是不太一样的, 可以说事务的实现依赖于 MVCC 特性, 但事务要比 MVCC 本身复杂得多. 如果不希望在读取时记录被修改, 锁才是唯一可行的。
回答二:共享锁还是存在的哦,在mysql5.6 innodb,RR隔离级别中。
使用主键索引去查询一条不存在的数据,就会加上s锁了。
你可以试一下:
开启两个事务用主键查询同一条不存在数据(使用select … for update)。
两个事务都会返回一个空结果。
此时,两个事务无论是谁都没办法以这个主键insert数据。
深入分析事务的隔离级别----非MySQL的处理方法,标准SQL事务规定的处理方法,用锁处理的
Redo log, bin log, Undo log
InnoDB中通过undo log实现了数据的多版本,而并发控制通过锁来实现。
undo log除了实现MVCC外,还用于事务的回滚。MySQL Innodb中存在多种日志,除了错误日志、查询日志外,还有很多和数据持久性、一致性有关的日志。
binlog,是mysql服务层产生的日志,常用来进行数据恢复、数据库复制,常见的mysql主从架构,就是采用slave同步master的binlog实现的, 另外通过解析binlog能够实现mysql到其他数据源(如ElasticSearch)的数据复制。
redo log记录了数据操作在物理层面的修改,mysql中使用了大量缓存,缓存存在于内存中,修改操作时会直接修改内存,而不是立刻修改磁盘,当内存和磁盘的数据不一致时,称内存中的数据为脏页(dirty page)。为了保证数据的安全性,事务进行中时会不断的产生redo log,在事务提交时进行一次flush操作,保存到磁盘中, redo log是按照顺序写入的,磁盘的顺序读写的速度远大于随机读写。当数据库或主机失效重启时,会根据redo log进行数据的恢复,如果redo log中有事务提交,则进行事务提交修改数据。这样实现了事务的原子性、一致性和持久性。
undo log: 除了记录redo log外,当进行数据修改时还会记录undo log,undo log用于数据的撤回操作,它记录了修改的反向操作,比如,插入对应删除,修改对应修改为原来的数据,通过undo log可以实现事务回滚,并且可以根据undo log回溯到某个特定的版本的数据,实现MVCC。