浅谈事务
一、什么是事务:
事务就是一组原子性的SQL查询,或者说一个独立的工作单元。
如果数据库引擎能够成功的对数据库应用该组查询的全部语句,那么久执行该组查询。如果其中有任何一条语句因为崩溃或其他原因无法执行,那么所有的语句都不会执行,就是说,事务内的语句,要么全部执行成功,要么全部执行失败。


二、事务的四大特性:

![]()
三、隔离级别:

READ UNCOMMITTED (未提交读)
在READ UNCOMMITTED 级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读。(ps: 脏读读的是没有提交的数据,假数据)
在实际应用中一般很少使用。
READ COMMITTED (提交读)
大多数数据库系统的默认隔离级别都是READ COMMITTED(MySQL不是,MySQL默认是可重复读)。
一个事务开始时,只能“看见”已经提交的事务所做的修改。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别也叫做不可重复读,因为两次执行同样的查询,可能会得到不一样的结果。
REPEATABLE READ (可重复读)
解决了脏读的问题。该级别保证了在同一个事务中多次读取同一条记录的结果是一致的。但是理论上,可重复读隔离界别还是无法解决另外一个幻读的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。**InnoDB和XtraDB存储引擎通过多版本并发控制(MVCC,Multiversion Councurrency Control )解决了幻读的问题。
**多版本并发控制。为每行记录添加了一个版本号(系统版本号),每当修改数据时,版本号加一。 在读取事务开始时,系统会给事务一个当前版本号,事务会读取版本号<=当前版本号的数据,这时就算另一个事务插入一个数据,并立马提交,新插入这条数据的版本号会比读取事务的版本号高,因此读取事务读的数据还是不会变
SERIALIZABLE (可串行化)
SERIALIZABLE是最高的隔离级别。它通过强制事务串行执行,避免了前面说的幻读的问题。简单来说,SERIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别。

事务的并发问题:
脏读:事务A读取了事务B更新的数据,然后B回滚,那么A读到的数据是脏数据。
不可重复读:事务A多次读取同一数据,事务B在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据,但是结果不一致。
幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表




浙公网安备 33010602011771号