1.数据库事务特性
1.1ACID特性
事务(Transaction)是数据库系统中:系统操作的一个逻辑单元,所有的操作要么全部成功,要么全部失败。
事务是区分文件存储系统和Nosql数据库的重要特性之一,且存在的意义是为了保证即使在并发情况下也能正确的执行crud操作。
事务需要保证的四个特性
A:原子性(atomicity)
一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的装填,就像这个事务从来没有执行过一样。原子性表现为操作不能被分割。
B:一致性(consistency)
在事务开始之前和事务结束之后,数据库的完整性没有被破坏。数据库要一直处于一致的装填,事务开始前是一个一致状态,事务结束后是另一个一致装填,事务将数据库从一个一致状态转移到另一个一致状态
C:隔离性(isolation)
数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读已提交(read committed)、可重复度(repeatable read)和串行化(Serializable)。
D:持久性(durability)
事务处理出书后,对数据的修改就是永久的,即便系统故障也不会丢失。
1.2事务隔离级别
在高并发的情况下,要完全保证其ACID特性是非常困难的,除非把所有的事务串行化执行,但带来的负面的影响将是性能大打折扣。很多时候我们有些业务对事务的要求是不一样的,所以数据库中设计了四种隔离级别,供用户基于业务进行选择。
数据库默认隔离级别:
Oracle中默认级别是Read committed
mysql中默认级别Repeatable read
#查看mysql的默认隔离级别
SELECT @@tx_isolation
#设置为读未提交
set tx_isolation='read-uncommitted';
#设置为读已提交
set tx_isolation='read-committed';
#设置为可重复读
set tx_isolation='REPEATABLE-READ';
#设置为串行化
set tx_isolation='SERIALIZABLE';
隔离级别 | 脏读(Dirty Read) | 不可重复度(NonRepeatable Read) | 幻读(Phantom Read) |
---|---|---|---|
未提交读 (Read uncommitted) | 可能 | 可能 | 可能 |
已提交读 | 不可能 | 可能 | 可能 |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(Serializable) | 不可能 | 不可能 | 不可能 |
脏读
一个事务读取到另一事务未提交的更新数据
session_1
#设置为读未提交
set tx_isolation='read-uncommitted';
BEGIN;
insert INTO `account` (accountName,user,money) VALUES ('222','cat',1000);
rollback;
commit;
session_2
#设置为读未提交
set tx_isolation='read-uncommitted';
SELECT * from account;
不可重复读
在同一事务中,多次读取同一数据返回的结果有所不同,换句话说,后续读取可以读到另一事务已提交的更新数据。相反,“可重复读”在同一事务中多次读取数据时,能够保证所读取数据一样,也就是后续读取不能读到另一事务已提交的更新数据。
事务B修改数据导致当前事务A前后读取数据不一致,侧重点在于事务B修改
当前事务读到了其他事务修改的数据
幻读
查询表中一条数据,如果不存在就插入一条,并发的时候却发现,里面居然有两条相同的数据。
事务A修改表中数据,此时事务B插入一条新数据,事务A查询发现表中还有没修改的数据,像是出现幻觉
事务A读到了事务B新增的数据,导致结果不一致,侧重点在于事务B新增数据