1、数据库事务的四大特性ACID
支持事务的数据库必须有这四大特性,否则不能保证数据的正确性。
- 原子性Atomicity:事务内所有操作共同组成原子包;要么全部成功,要么全部失败,保存特殊因素导致数据库宕机,仍然正确。
- 一致性Consistency:事务执行前后都必须处于一致性状态;一致性基于原子性,原子性保证一个事务内的所有操作同一性,但是如果事务提交一半,会不会有中间结果呢?为了防止这样情况,要求提交前后,只可能存在事务提交前和事务提交后,不可能出现中间状态。
- 隔离性Lsolation:事务可以有多个原子包的形式并发执行,互不干扰。但是由于多个事务可能操作同一个资源,不同的事务为了保证隔离性,会有很多锁方案(锁就会被面试官提问了)。
- 持久性Durability:事务提交,数据库状态永久发生了改变;
2、并发事务引起的问题(问题详情要知道)
1)修改时允许修改:丢失更新;
两个事务同时更新一行数据,但是第二个事务中途失败退出,导致两个数据修改都失效。
2)修改时允许读取:脏读;
无效读出,一个事务读取另一个事务还木有提交的数据。例如:事务T1修改了一行数据,但还没提交。这是事务T2读取了被T1修改的数据,之后事务T1因为某种原因Rollback了,那么事务T2读取的数据就是脏的。
3)读取时允许修改:不可重复读;
两次查询返回不同的结果。事务T1读取一个数据,事务T2读取并修改了这个数据,T1为了对读取值进行检验而再次读取该数据,便得到不同的结果。
4)读取时允许插入:幻读;
事务操作中进行两次查询,第二次查询结果包含了第一次查询中未出现的数据或者缺少数据。如:系统管理员A将数据库中所有学生成绩从具体分值改为ABCD等级,但是管理员B,这时插入了一个分值数据,管理员A改结束后发现有个没改过来,似乎出现了幻读。
隔离用来设定数据库的并发行为,避免以上问题的发生;
四种事务隔离级别
- 1)Read Uncommitted读取未提交的内容 :最低级别,任何情况都无法保证。
- 在这个隔离级别,所有事务可以看到其他未提交事务的执行结果。
- 当操作同一行数据,读事务允许其他读事务和写事务,未提交的写事务禁止其他写事务(但允许其他读事务)。
- 可以防止更新丢失,但是不能防止脏读、不可重复读、幻读。
- 通过排他写锁实现。
- 2)Read Committed读取提交的内容 :可避免脏读的发生。
- (优先考虑,能避免脏读和更新丢失,并发性能好,不可重复和幻读的问题可以通过悲观锁或乐观锁控制)
- (除MySQL)其他数据库默认隔离级别,一个事务只能看到已经提交事务所作的改变,支持不可重复读。
- 以操作同一行数据为前提,读事务允许其他读事务和写事务,未提交的写事务禁止其他读事务和写事务。
- 此隔离级别可以通过“瞬间共享读锁”和“排他写锁”实现。
- 3)Repeatable Read 可重读 :可避免脏读、不可重复读的发生。
- MySQL默认事务隔离级别,确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。但是会导致幻读。
- InnoDB和Falcon存储引擎通过多版本并发控制机制,解决该问题;
- 以操作同一行数据为前提,读事务禁止其他写事务(但允许其他读事务),未提交的写事务禁止其他读事务和写事务。
- 此隔离级别可以防止更新丢失、脏读、不可重复读,但不能防止幻读。
- 此隔离级别可以通过“共享读锁”和“排他写锁”实现。
- 4)Serializable 可串行化: 可避免脏读、不可重复读、幻读的发生。Oracale
- 强制事务排序,每个读的数据行加上共享锁。可能导致大量的超时现象和锁竞争。
- 提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。
- 此隔离级别可以防止更新丢失、脏读、不可重复读、幻读。
- 如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。