MySQL数据库入门(六)

事务管理

一、事务管理

事务是针对数据库的一组操作,它可以由一条或多条SQL语句组成,同一个事务的操作具备同步的特点,

如果有一条语句无法执行,那么所有的语句都不会执行,也就是说,事务中的语句要么都执行,要么都不执行。

在数据库中使用事务时,需要先开启事务,使用START TRANSACTION;

事务开启之后就可以执行SQL语句,SQL语句执行成功后,需要使用相应语句COMMIT;提交事务。

事务中操作的语句都需要使用COMMIT语句手动提交,只有事务提交后其中的操作才会生效。

如果不想提交当前的事务还可以使用相关的语句取消事务(也称回滚),ROLLBACK;

ROLLBACK只能针对未提交的事务执行回滚操作,已经提交的事务是不能回滚的。

事务必须同时满足4个特性:即原子性、一致性、隔离性、持久性。

原子性:一个事务必须被视为一个不可分割的最小工作单元,只有事务中所有的数据库操作都执行成功,

才算整个事务执行成功,事务中如果有任何一个SQL语句执行失败,已经执行成功的SQL语句也必须撤销,数据

扫描二维码关注公众号,回复: 2396221 查看本文章

库的状态退回到执行事务前的状态。

一致性:事务将数据库从一种状态转变为下一种一致的状态。

隔离性:也可以称为并发控制、可串行化、锁等。当多个用户并发访问数据库时,数据库为每一个用户开启

的事务,不能被其他事务的操作数据所干扰,多个事务之间要相互隔离。

持久性:事务一旦提交,其所做的修改就会永久保存到数据库中,即使数据库发生故障也不应该对其有任何

影响。

二、事务的隔离级别

在MySQl中,事务有4种隔离级别。

1. READ UNCOMMITTED

 READ UNCOMMITTED(读未提交)是事务中最低的级别,该级别下的事务可以读取到另一个事务中未提交

的数据,也被称为脏读(Dirty Read),这是相当危险的。由于该级别较低,在实际开发中避免不了任何情况,所以

一般很少使用。

2. READ COMMITTED

大多数的数据库管理系统的默认隔离级别都是READ COMMITTED(读提交),该级别下的事务只能读取其他

事务已经提交的内容,可以避免脏读,但不能避免重复读和幻读的情况。重复读就是在事务内重复读取了别的线程已经

提交的数据,但两次读取的结果不一致。原因是查询的过程中其他事务做了更新的操作。幻读是指在一个事务内两次查

询中数据条数不一致,原因是查询的过程中其他的事务做了添加操作。这两种情况并不算错误,但有些情况是不符合实

际需求的。

3. REPEATABLE READ

REPEATABLE READ (可重复读)是MySQL默认的事务隔离级别,它可以避免脏读、不可重复读的问题,确保

同一事务的多个实例在并发读取数据时,会看到同样的数据行。虽然,理论上,该级别会出现幻读的情况,但是MySQL

的存储引擎通过多版本并发控制机制解决了该问题。因此,该级别是可以避免幻读的。

4. SERIALIZABLE

SERIALIZABLE(可串行化)是事务的最高隔离级别,它会强制对事务进行排序,使之不会产生冲突,从而解决

脏读、幻读、重复读的问题。实际上,就是在每个读的数据行上加锁。这个级别,可能导致大量的超时现象和锁竞争,

实际应用中很少使用。

这四种隔离级别可能会产生以下问题。

(1)脏读

脏读是指一个事务读取了另外一个事务未提交的数据。

例如:a账户要给b账户转账100元来购买商品,当a账户开启了一个事务后,执行了update语句做了转账操作,

如果a账户先不提交事务,通知b账户来查询,由于b账户的隔离级别较低,此时就会读到a事务中尚未提交的数据,发

现a确实给自己转了100元,然后给a发货,等b发货成功后a就将事务回滚,此时b就会受到损失,这就是脏读造成的。

(2)不可重复读

不可重复读(NON-REPEATABLE READ)是指事务中两次查询的结果不一致。原因是查询的过程中其他事务

做了更新操作。

例如:银行在做统计报表时,第一次查询a账户中有1000元,第二次查询a账户中有900元,原因是统计期间a

账户取出了100元,这样就会导致多次统计报表的结果不一致。

不可重复读和脏读的不同:脏读是指读取前一个事务未提交的脏数据,不可重复读是在事务内重复读取了别的

线程已经提交的数据。

(3)幻读

幻读(PHANTOM READ)又被称为虚读,是指在一个事务内两次查询中数据条数不一致,幻读和不可重复读

有些类似,同样是在两次查询过程中,不同的是,幻读是由于其他事务做了插入记录的操作,导致记录数有所增加。

例如:银行在做统计报表时统计account表中所有用户的总额时,此时总共有三个账户总共金额是3000,这时,

这时,新增了一个账户,并且存入了1000元,这时银行再统计时发现账户的总金额变为4000,造成了幻读的情况。

(4) 可序列化

可序列化(SERIALIZABLE)是事务的最高隔离级别,它在每个读的数据行上加上锁,使之不可能相互冲突,

因此会产生大量的超时现象。

如果一个事务使用了SERIALIZABLE隔离级别时,在这个事务没有被提交前,其他的线程只能等到当前操作完

成后,才能操作,这会非常耗时,而且会影响数据库的性能,通常情况下是不会使用这种隔离级别的。

猜你喜欢

转载自blog.csdn.net/tc_1337/article/details/81149343