当前位置: 首页 > 科技观察

详解MySQL事务的四大特性和隔离级别

时间:2023-03-19 12:08:52 科技观察

1、事务的四大特性(ACID)1.1、原子性(Atomicity)原子性是指一个事务中包含的一系列操作要么全部成功,要么全部成功回滚。有部分成功,也有部分回滚,是一个不可分割的整体操作。1.2.一致性(Consistency)一致性可以理解为事务对数据完整性约束的遵守情况,这可能包括主键约束、唯一索引约束、外键约束等。交易执行前后,数据处于合法状态,不会违反任何数据完整性。以转账为例。A和B加起来是5000元。不管A和B怎么转钱,转多少次,A和B加起来的钱永远是5000元。简而言之,一致性可以理解为保证数据的完整性。1.3.隔离隔离是指当多个用户并发操作数据库时,比如操作同一张表,数据库为每个用户开启的事务不会受到其他事务的干扰或影响,事务之间相互独立。的。1.4、持久性(Durability)持久性是指事务一旦提交,对数据库中数据的更改是永久性的,即使数据库出现故障,事务提交的数据也不会丢失。2.事务隔离。隔离事务。当多个线程启动事务操作数据库中的数据时,数据库必须能够进行隔离操作,以保证每个线程获取数据的准确性;如果不考虑事务的隔离,会出现以下问题;2.1、脏读脏读是指一个事务在处理过程中读取了另一个事务未提交的数据。比如A给B转钱时updateaccountsetmoney=money+100wherename='B';updateaccountsetmoney=money-100wherename='A'当只执行了第一条SQL的时候,A通知B查账,B发现钱确实到了(此时也就是发生了脏读),而不管第二条SQL是否执行,只要事务没有提交,所有的操作都会回滚,那么当B检查以后再开户,他会发现钱其实并没有转账。重复读和不可重复读是指对于数据库中的某条数据,在一个事务范围内多次查询返回不同的数据值。这是因为它在查询间隔期间被另一个事务修改并提交了。例如,事务T1正在读取某条数据,事务T2立即修改数据并提交事务到数据库。当事务T1再次读取数据时,得到的结果不同,出现不可重复读。不可重复读和脏读的区别在于,脏读是指一个事务读取了另一个事务未提交的脏数据,而不可重复读是指读取了前一个事务提交的数据。在某些情况下,不可重复读取不是问题。比如我们多次查询某个数据,当然最后查询的结果是主要的。但在其他情况下,可能会出现问题。比如对于同一份数据,A和B在顺序查询的时候可能不一样,A和B可能会打架...2.3.幻读幻读是发生在事务没有独立执行时的一种现象。例如,事务T1将表中所有行的一个数据项从“1”修改为“2”。这时,事务T2往这张表中插入了一行数据,并且这条数据的值还是“1”,并提交给了数据库。但是如果用户操作事务T1查看刚刚修改的数据,会发现还有一行没有修改。事实上,这一行是从事务T2中添加的,这似乎是幻觉。这就是幻读的发生。幻读和不可重复读都是读取另一个已经提交的事务(这与脏读不同)。不同的是,不可重复读查询的是同一个数据项,而幻读针对的是一批整体数据(比如数据的条数)3.MySQL隔离级别Serializable(序列化):可以避免脏读的发生,非-可重复读和幻读>*可重复读(repeatablereads):可以避免脏读、不可重复读的发生>*已提交读(readcommitted):可以避免脏读的发生>*未提交读(readuncommitted):最低级别,无论如何都不能保证以上四个隔离级别最高的是Serializable级别,最低的级别是Readuncommitted。当然,级别越高,执行效率越低。像Serializable这样的级别就是对表进行加锁(类似于Java多线程中的锁),让其他线程只能在锁外等待),所以选择哪种隔离级别要根据实际情况而定。3.1.MySQL和Oracle隔离级别的比较MySQL支持以上四种隔离级别。默认的隔离级别是Repeatableread(可重复读)。Oracle只支持Serializable(序列化)级别和Readcommitted(已提交读)。level,默认隔离级别是Readcommitted(读提交)查看mysql事务的隔离级别select@@tx_isolation4,举例说明事务的隔离级别4.1、Repeatableread(可重复读)开启两个事务A和B,分别对同一张表的数据进行操作,操作过程如下:结果:在Repeatableread的隔离级别下,T4得到的结果仍然是Tom:此时如果提交事务A,然后查询,得到的结果会是最新的Result:4.2、Readcommitted(读提交)现在看设置隔离级别为readcommitted,返回的结果是什么setsessiontransactionisolationlevelreadcommitted注意:这个修改只对当前session有效。如果要全局修改隔离级别,需要到mysql安装目录下my.ini末尾添加transaction-isolation=REPEATABLE-READ。结果:在Readcommitted隔离级别下,T4得到的结果是最新的,说明committed已经被读取了: