Mysql数据库特性
1、原子性(atomicty):
一个事物必须视为不可分割的最小单元。整个事务中的所有操作要么全部提交成功,要么全部失败回滚。
2、一致性(consistency):
举例说明:一个事务中有四个执行语句,前两个语句执行成功,第三个、第四个语句执行时崩溃,因为事务没有提交,所以事务中所做的修改也不会保存到数据库。
官方说明:数据库总是由一个一致性状态转换到另一个一致性状态。
个人理解原子性和一致性:原子性是在事务提交后判断,而一致性重在判断事务是否提交。
3、隔离性(isolation):
一个事务所做的修改在最终提交以前,对其他事务是不可见的。
4、持久性(durability):
一旦事务提交,其所做的修改就会永久的保存到数据库中,此时就算系统崩溃,数据也不会丢失。
事务的隔离机制
1、未提交读(read uncommitted):
事务的修改即使没有提交,对其他事务是可见的,会出现脏读的情况。
2、提交读(read committed):
一个事务开始时,只能“看见”已经提交的事务所做的修改。一个事务同样执行两个查询,会可能得到不一样的结果。这种情况叫做不可重复读。
3、可重复读(Repeatable Read),Mysql默认的隔离方式:
可重复读可以避免不可重复读的问题,但是不能解决幻读的问题。
注:Mysql通过多版本控制(MVCC)解决幻读的问题。
4、可串行化(serializable):
强制事务串行执行,避免幻读的问题,serializable会在读取的每一行数据都会加锁,会导致大量的超时和锁等待的问题。
场景:非常需要确保数据的一致性,可以接收没有并发的情况下。
脏读:一个可是可以读到其他事务没有提交的事务。
不可重复读:在一个事务里使用两次同一条查询,有一个事务在这个事务提交前修改了查询的数据,那么就会使这个事务两次查询的结果不一致。
幻读:在一个事务里使用两次同一条查询,有一个事务在这个事务提交钱,增加了一条符合此事务查询的结果,那么第二次查询就会多出一条数据,叫做幻读。
隔离级别 | 脏读 | 不可重复读可能性 | 幻读可能性 | 加锁读 |
READ UNCOMMITTED | √ | √ | √ | × |
READ COMMITTED | × | √ | √ | × |
REPEATABLE READ | × | × | √ | × |
SERUALIZABLE | × | × | × | √ |
Mysql中的悲观锁和乐观锁:
MVCC(多版本并发控制)分为乐观并发控制和乐观并发控制。
悲观锁:悲观锁指的是假设更新冲突发生,所以不管冲突是否真的发生,都会使用锁机制。
悲观锁会锁住读取的数据,方式其他事务读取和更新这些记录。其他事务会一直堵塞,知道这个事务结束。
悲观锁是在使用了数据库的事务隔离功能基础上,独享占用的资源,以此保证数据读取的一致性。
Select … for update。
这样会锁住查询语句,当事务未提交时,其他事务查询符合当前语句的数据都会阻塞,所以悲观锁尽量不要使用。
乐观锁:乐观锁是在事务中不使用行级锁,在大多数情况下避免了加锁操作,因此开销更低。乐观锁大多都实现了非堵塞的读操作,写操作也只锁定必要的行。
乐观锁是在数据库表里增加一个版本号,每次查询的时候根据版本号进行判别,从而筛选数据。
注意:MVCC只在REPEATABLE READ和READ COMMITTED两个隔离级别下的工作。其他两个隔离机制级别都和MVCC不兼容。因为READ UNCOMMITTED总是读取最新的数据行,而不是符合当前事务版本的数据行。而SERIALIZABLE则会对所有读取的行都加锁。