事务特性
A:原子性:操作原子性,一次事务内的操作,要么同时成功,要么同事失败
C:一致性:数据一致性,修改的数据是同步一致的,不存在有些数据保存成功有些数据不成功
I:隔离性:隔离机制用于保证事务再不收外部并发操作影响的独立环境中执行,是由有几个级别:读未提交,读已提交,可重复读,串行,来控制事务和事务之间的影响
D:持久性:数据是可以持久化的写入磁盘的,及时宕机数据也不会丢失
隔离性的影响
脏写:多线程对用一条数据进行读写操作的时候,A线程读-》B线程读-》A线程写-》B线程写。B线程写数据时,不是基于数据库最新的数据进行修改的,还是根据自己线程内存中的值进行修改,导致将A线程的写操作覆盖了
脏读:A事务修改数据但没有提交,这时B事务需要对同一条数据进行读写操作,如果B事务读到了A事务修改但还没有提交的数据后,A事务回滚了,那么B事务读取到的就是过程中的脏数据
不可重复读:在同一事务内,同一个查询语句多次执行,如果查询到的数据每次都不一样,则大大提高编程的复杂性,也说明被其他事务的操作影响到了,不满足隔离性
幻读:A事务在操作过程中,可以查询到其他事务新增的数据,也不满足隔离性
mysql提供了隔离级别,来不同程度了控制事务隔离性和兼顾并发性:
不同应用对隔离级别的要求不同,多数应用对幻读并不敏感,更关心的是数据并发访问能力,所以mysql默认的事务隔离级别是可重复读
#常看当前数据库的事务隔离级别:
show variables like 'tx_isolation';
#设置事务隔离级别:
set tx_isolation='REPEATABLE-READ';
数据库锁
锁是为了保证数据并发读写下的一致性,但是锁冲突也是印象数据库访问性能的一个重要因素
乐观锁:常见的CAS锁,由应用端实现,通过修改时对数据版本的判断,确定是否被其他线程修改
读锁:共享锁,读读共享,读写互斥,多个读操作对同一条数据不会互相影响
写锁:互斥锁,读写互斥,写写互斥,同时只有一个线程可以进行写操作,期间会阻断其他写操作
表锁&行锁
MyIsam表只支持表锁,会再执行select前自动给设计的所有表加读锁,update/insert/delete操作时,会自动给涉及的表加写锁,锁粒度太大,不适用于目前多并发的场景
目前主流使用的InnoDB是支持事务和行锁的,在查询时不会加锁,而是通过MVCC(多版本控制机制)实现可重复读,在update,insert,delete操作时会加行锁,这里需要注意:锁是加载索引上的,如果对费索引字段进行写操作,行锁会升级成表锁!
select * from bus_user lock in share mode;
select * from bus_user where a = 2 for update;
这样其他session只能读这行数据,修改则会被阻塞,直到锁定行的session提交s事务
show status like 'innodb_row_lock%';