一、什么是事务
事务(transaction)是一组操作。里面有很多小的操作。如果其中某个小操作(原子的,不可分割的操作了)出了问题,那么这个事务就不能被提交,需要回滚。
二、事务的特性
ACID
- 原子性:事务中的小操作是原子的,不可分割。
- 一致性:事务执行前后,数据应该是完整一致的。
- 隔离性:事务执行过程中,不应该收到其他事务的影响。
- 持久性:持久化到数据库。
三、事务的安全隐患
- 读
- 脏读:A事务,读到B事务的暂未提交的数据。注意,B事务的数据没有提交,没有更新到数据库。但是会被其他事务读到。
- 不可重复读:A事务先读了一次,B事务提交了自己的修改。A事务执行了其他的逻辑后,在查询一次,发现两次数据不一样。
- 幻读:同上,只是数据不是修改,而是增加或者减少
- 写
- 丢失更新:对于这样一个数据(name:zhangyi age:18)。A事务修改name为zhang2。B事务修改age为1。然后A先提交,B再提交。那么A的修改会被B的修改覆盖,造成丢失。注意:事务以开启的时候读到的数据为准,像是读取事务开启那个时候的快照)。
四、事务读安全问题解决方法:隔离级别
- READ UNCIMMITTED:读未提交。存在隐患:各种隐患都有。
- READ COMMITTED:读已提交。存在问题:不可重复读。
- REPEATABLE READ:可重复读。存在问题:幻读。
- SERIALIZABLE:串行化。存在问题:效率低。
五、事务写安全问题解决方法(解决丢失更新问题):锁
- 悲观锁:认为肯定会出意外,那么就一致加锁。在查询的时候,加上for update。
- 乐观锁:程序员自己控制。增加一个version变量,判断版本号是否一致。若不一致,先更新自己(获得数据库最新的,这样就不会覆盖之前的了,不会丢失),再提交。类似于svn。