数据库事务和隔离级别
任何支持事务的数据库,都必须具备四个特性 ( ACID ),才能保证事务 ( Transaction ) 中数据的正确性。
- 原子性 ---> Atomicity
- 事务包含的操作,要么全部成功,要么全部失败回滚
- 一致性 ---> Consistency
- 事务必须使数据库从一个一致性状态变换到另一个一致性状态
- 也就是说一个事务执行之前和执行后都必须处于一致性状态
- 隔离性 ---> Isolation
- 多个并发事务之间要相互隔离
- 每个事务都感觉不到有其他事务再并发的执行
- 持久性 ---> Durability
- 一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的
- 即便在数据库系统遇到故障的情况下,也不会丢失提交事务的操作
事务的隔离:多个并发事务同时访问一个数据库时,一个事务不应该被另一个事务所干扰,每个并发的事务间要相互进行隔离。
一般数据库,都包括一下四种隔离级别
- 读未提交 ---> Read Uncommitted
- 顾名思义,就是可以读到未提交的数据
- 允许另一个事务读到一个事务未提交的数据
- 在这种隔离级别下,查询是不会加锁的
- 由于查询不加锁,所以这种隔离级别一致性最差
- 可能产生"脏读"、"不可重复读"、"幻读"
- 读已提交 ---> Read Committed
- 只能读到已提交的数据
- 保证一个事务修改的数据提交后才能被另一个事务读取到
- 这是各个系统中最常用的隔离级别,也是 SQL Server 和 Oracle 默认的隔离级别
- 这种隔离级别能有有效的避免脏读
- 可重复读 ---> Repeated Read
- 确保事务可以多次从一个字段中读取相同的值,在事务持续期间,禁止其他事务对此字段的更新
- 可避免脏读和不可重复读
- 可能产生"幻读"
- MySQL 默认的隔离级别
- 串行化读 ---> Serializable
- 最严格的事务隔离级别
- 要求所有事务串行执行,不能并发执行
- 可避免脏读,不可重复度,幻读
若不考虑事务的隔离性,会发生一下几种问题
- 脏读
- 在一个事务处理过程中,读到了另一个未提交事务的数据
- 不可重复读
- 对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询隔离,被另一个事务修改提交了
- 幻读(虚读)
- 一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。
- 如果事务中都使用快照读,那么就不会产生幻读现象,但是快照读和当前读混用就会产生幻读
四种隔离级别,可能产生的问题