数据库事务隔离级别
数据库隔离级别:是在在数据库操作中,为了有效保证并发读取数据的正确性提出的。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
数据库的几种隔离级别:
- READ UNCOMMITTED(读未提交数据):允许事务读取未被其他事务提交的变更数据,会出现脏读、不可重复读和幻读问题。
- READ COMMITTED(读已提交数据):只允许事务读取已经被其他事务提交的变更数据,可避免脏读,仍会出现不可重复读和幻读问题。
- REPEATABLE READ(可重复读):确保事务可以多次从一个字段中读取相同的值,在此事务持续期间,禁止其他事务对此字段的更新,可以避免脏读和不可重复读,仍会出现幻读问题。
- SERIALIZABLE(串行化):确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,可避免所有并发问题,但性能非常低。
Oracle支持两种事务隔离级别: READ COMMITTED(默认事务隔离级别),SERIALIZABLE(序列化)
MySQL支持四种事务隔离级别,其中REPEATABLE READ(RR可重复读)为默认事务隔离级别。
通过上面可以知道多事务同时运行,如果不采用以上四种隔离机制,可能会产生多个并发问题,其中包括脏读、不可重复读和幻读,下面就解释下这几种并发问题:
存在两个事务(A,B)同时运行
- 脏读:事务A读取了已经被事务B修改但还未提交的字段,由于事务B回滚,则事务A读取的是脏数据。
- 不可重复读:不可重复读与脏读逻辑类似。主要在于事务B在事务A第二次读取时,跟新了数据。导致事务A前后两次读取的数据不一致。
- 幻读:事务A第二次查询时,读到了事务B提交的数据。
- 不可重复读和幻读的区别: 不可重复读是值不同,幻读是数据条数不同。
在mysql中通过MVCC(快照读)和next-key(当前读)两种模式解决幻读问题。
举例:https://www.cnblogs.com/liyus/p/10556563.html
数据库事务的特性:原子性、一致性、隔离性、持久性:
- 原子性:事务的原子性指的是,事务中包含的程序作为数据库的逻辑工作单位,它所做的对数据修改操作要么全部执行,要么完全不执行,这种特性称为原子性。(简单地说就是,几个对于数据库的操作要么全执行,要么全不执行,即同时成功起作用或同时失败没影响)
- 一致性:事务一致性值得是在一个事务执行之前和执行之后数据库都必须处于一致性状态(中途是否一致不用管),这种特性称为一致性。(如果数据库的状态满足所有的完整性约束,就说该数据库是一致的。一致性处理数据库中对所有语义的保护。如:客户K1要向客户K2转账,K1账户减少的金额就是K2账户增加的金额,在转账之前K1和K2账户的金额之和与转账之后K1和K2账户的金额之和是一样的,在转账期间可能不满足这种一致性,但事务前后是数据库数据是一致的)
- 隔离性:隔离性指的是并发的事务是相互隔离的。(一个事务内部的操作及正在操作的数据必须封装起来,不被其它企图进行修改的事务看到)
- 持久性:持久性指当系统或介质发生故障时,确保已提交的更新不能丢失。(一个事务提交,DBMS保证它对数据库中数据的改变应该是永久性的,可以经受任何系统故障,持久性通过数据库备份和恢复来保证)
查询mysql事务隔离级别的sql操作:
1.查看当前会话隔离级别 select @@tx_isolation;
2.查看系统当前隔离级别 select @@global.tx_isolation;
3.设置当前会话隔离级别 set session transaction isolatin level repeatable read;
4.设置系统当前隔离级别 set global transaction isolation level repeatable read;
学海无涯 代码作伴