1. 事务的特性
事务:一组业务操作,要么全部成功,要么全部不成功。
特性:ACID
- 原子性:
整体
,事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做。 - 一致性:
数据
, 事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。 - 隔离性:
并发
, 一个事务的执行不能其它事务干扰。 - 持久性:
结果
,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。
2. Mysql 的四种隔离级别
2.1 隔离问题:
-
脏读:一个事务读到另一个事务未提交的内容.
- 当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
-
不可重复读:一个事务读到另一个事务已提交的内容(update)
- 在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在
一个事务内两次读到的数据是不一样
的,因此称为是不可重复读。
- 在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在
-
虚读(幻读):一个事务读到另一个事务已提交的内容(insert)
- 当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中
插入一行新数据
。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样
。
- 当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中
2.2 隔离级别
-
读未提交(read uncommittd):在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。
存在3个问题
。 -
读已提交(read committed):一个事务只能看见已经提交事务所做的改变。
解决:脏读。存在2个问题。
-
可重复读(repeatable read):这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。
解决:脏读、不可重复读。存在1个问题。
-
串行化(serializable):单事务。这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
没有问题。
3. 悲观锁和乐观锁
3.1 悲观锁
悲观锁:(数据库提供实现) . 默认认为一定会发送别人要修改我使用的数据. 那我就可以为我读取的数据加锁。丢失更新肯定会发生
-
读锁/共享锁
:读锁可被其他线程所共享,如果是读取的话大家都可以用这把锁读到数据.- select * from table lock in share mode(读锁、共享锁)
-
写锁/排他锁
:(独占). 写锁不能共享,只要有人为数据加入了写锁,其他人就不能为数据加任何锁.- select * from table for update (写锁、排它锁)
3.2 乐观锁
乐观锁:需要自己实现, 丢失更新肯定不会发生
在表中提供一个字段(版本字段),用于标识记录。如果版本不一致,不允许操作。