一、什么是事务?
事务是由一组sql语句组成的逻辑处理单元。
二、事务的ACID属性
-
原子性(Atomicity)
事务是一个原子操作单元。特点是不可再分,当操作中有多个步骤时,要么全成功,要么全失败。 -
一致性(Consistent)
在事务开始与完成时,数据都必须保持一致状态,这意味着所有相关数据规则都必须应用于事务的修改,以保持数据的完整性。
例如,A向B转账,不可能A扣了钱,B却没收到。 -
隔离性(Isolation)
数据库系统提供统一的隔离机制,保证每个事务都在单独的环境执行,事务之间互不影响。
这意味着事务之间处理过程是对其他事务不可见的。 -
持久性(Durable)
事务完成后,它对数据的修改时永久性的,即使出现系统宕机,数据依然能恢复,存在于数据库。
三、事务并发带来的4类问题
-
脏读(Dirty Reads)
事务A读取到了事务B修改但尚未提交的数据,然后事务B回滚了,因此事务A基于此数据做的操作都是无效的,就是读到了脏数据(实际上应该存在的数据),所以叫脏读。 -
脏写或丢失更新(Lost Update)
第一类丢失更新:撤销(rollback)一个事务时,把其他事务已经提交更新的数据给回滚掉了。
第二类丢失更新:提交(commit)一个事务时,把其他事务已经提交更新的数据给覆盖掉了。 -
不可重复读(Non-Repeatable Reads)
在事务A中,按相同的条件执行查询过的sql,返回结果发生了修改或被删除了,这种现象叫做“不可重复读”。 -
幻读(Phantom Reads)
在事务A中,按相同的条件执行查询过的sql,返回结果中有新数据(其他事务插入的数据),就好像发生了幻觉一样,被称为“幻读”。
四、事务的四种隔离级别
-
读未提交(Read Uncommitted, RU)
当前事务读取了其他事务还未提交的数据。
由于可能会造成脏读,所以实际中很少使用。 -
读已提交(Read Committed, RC)
事务A修改并提交的数据才会对其他事务可见,所以可以解决脏读问题。
多数RDBMS的默认隔离级别都是读已提交,例如Oracle,PostgreSQL,SqlServer,但Mysql不是。 -
可重复读(Repeatable Read, RR)
在同一事务中多次读取相同记录的结果是一致的,所以解决了脏读和不可重复读的问题,但未解决幻读。 -
串行化(Serializable)
串行化是最高的隔离级别,它通过强制事务串行执行,避免了脏读、不可重复读、幻读问题。
简单来说,串行化会在读取的每一行数据上都加上锁,所以可能导致大量的超时和锁征用问题。
实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况才考虑用该级别。
总结:
数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大。
查看当前数据库的事务隔离级别
mysql8中,记录数据库隔离级别的字段名称为 ‘transaction_isolation’,默认级别为‘可重复读’。
mysql5.7中,记录数据库隔离级别的字段名称为 ‘tx_isolation’,查询语句为select @@tx_isolation;
mysql8中事务默认隔离级别.png
网友评论