隔离性要求 要求并发执行的事务之间互相隔离,互不影响
但是并发程序可能会两个程序尝试同时读或者一个正在读一个正在写,这些都可能出现问题,于是数据库通过隔离性来避免这些问题。
事务的隔离强度分类
1.可序列化隔离 (Serializable Isolation) :即数据库保证事务之间的运行结果与串行执行 的结果一致。(强隔离,通过加锁,但会大大降低性能,无法并发)
2.读已提交(Read Commited) 基础的事务隔离,保证读只能读已经提交的数据,写只能覆盖已经提交的数据。
3.快照隔离(Snapshot Isolation) 也被叫做可序列化(Serializable)或者可重复读(Repeatable Read) 每个事务都从数据库的快照中读取数据,由于每次读都是从过去的某个快照中读数据,因此不会出现读取不一致的结果。这样就需要实现多版本并发控制(MVCC) 因为不同事务需要读取不同时间点的数据库快照而不是 Read Commited 的中只需要维护 commited 和 uncommited
隔离性处理 的问题
1.脏读(dirty read):
一个事务在处理过程中读取了另外一个事务未提交的数据
eg txn A 开启,txnB 开启,txnB修改数据,txnA查询数据,查询查到了已经修改的脏的数据,但是之后如果 txnB事务回滚,txn 查询到的就成为了镜花水月。
Read Commited 是最弱的隔离级别,但是也可以处理脏读的情况,即只可读可改 commited 的数据,如例子中 txnA 只能查询到 txnB 之前的数据,或者 txnB commited 之后 txnA 再查询再可以读到修改之后的数据。
2.不可重复读(non-repeatable read)
指一个事务范围内,多次查询某个数据,却得到不同的结果。
因为在一个事务的两次读取过程中间可能会出现并行的其他事务提交,导致读取到不同的数据。
eg txnA 开启 txnA 查询 txnB 开启 txnB 修改 txnB 提交 txnA 查询 txn A 提交,这样就出现了查询不一致的情况。
Read Commited 无法解决该问题,在大多数情况下问题不大,因为最终数据还是按照初始想法改变了,只是出现了临时的查询不一致的情况,很多数据库的默认隔离级别。
但是在某些情况下无法容忍这种临时不一致的状态。如备份的时候,某个数据已经被备份写入备份数据了,但是此时又来一个修改,这样最终导致备份的数据不一致的情况,这是致命的!!! 因此就需要更强一种的隔离方式 Snapshot Isolation来处理不可重复读问题
3.幻读(phantom read)
幻读问题是在事务不独立执行的时候出现的问题。
eg txnA开启 txnB 开启 txnA 查询发现有记录1条 txn B 插入一条新记录 txn B提交 txnA 查询发现有记录2条 由于txnA和 txnB 并不是操作的同一条记录,因此不算重复读。幻读和重复读都是读取了另一条已经提交的事务导致的问题,但是不可重复读是查询和修改的是同一个数据项,而幻读针对的是一批数据整体。
而要处理这个问题,Snap Isolation 就不够了,就需要更强的隔离级别Serializable串行化。
这就是花费最大但是最可靠的事务给了级别。写加写锁,读加读锁,出现读写冲突,后来的事务必须等先来事务处理完才能执行,这样事务保证了上述三种情况的发生,事务100%隔离。
这里只是简单提及了数据库事务处理中的三个问题和三种隔离级别。剩余还有一些关于这些锁的实现和其它的内容还在学习中。具体而言要根据应用选择对应的隔离级别。如重要的银行处理肯定是需要用串行化来保证完全不出错,但是对于其他的就具体根据应用而论了。
标签:txnB,事务,txnA,隔离,数据库,事务处理,查询,ACID,数据 From: https://www.cnblogs.com/newuser233/p/16720668.html