MySQL事务总结

事务的概念:事务是指逻辑上的一组操作,这组操作要么同时完成要么同时不完成.

例如A转账给B,从数据库的角度来看,A账户的钱减少,B账户的钱增加,这样才算是一次完整的转账。

如果A在转账的过程中,出现了意外的情况,A的钱减少了,而B的钱没有增加,这次的事务就不完整。只有当两个操作同时完成时,才能认为转账完成。这样就需要通过事务来操作。把转账的两步在一个事务中进行操作,只有当两个步骤都完成时,才提交事务,如果有任何一步没有完成,就回滚事务。回滚可以把结果恢复到事务开启之前的数据状态。

在MySQL中通过start transaction可以开启一个事务,然后在这个事务中做需要的操作,当操作完成时,使用commit来提交事务。如果中间有任何的问题,可以通过rollback来回滚结束事务。

事务可以通过rollback和commit来结束,rollback是不保存在事务中的操作,恢复数据到开启事务之前的状态。commit是把在事务中的修改,持久化到数据库。

MySQL默认是自动提交事务的,也就是说如果没有使用start transaction命令,那么每一次对数据库的操作,都会自动commit持久化。

事务的四大特性:(ACID)

原子性: 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性:如果事务执行之前数据库是一个完整性的状态,那么事务结束后,无论事务是否执行成功,数据库仍然是一个完整性状态.数据库的完整性状态是指当一个数据库中的所有的数据都符合数据库中所定义的所有的约束,此时可以称数据库是一个完整性状态.

隔离性:事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

持久性:持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

数据库中的四大隔离级别:

Read uncommitted — 不防止任何隔离性问题,具有脏读/不可重复度/虚读(幻读)问题
Read committed — 可以防止脏读问题,但是不能防止不可重复度/虚读(幻读)问题
Repeatable read — 可以防止脏读/不可重复读问题,但是不能防止虚读(幻读)问题
Serializable — 数据库被设计为单线程数据库,可以防止上述所有问题

脏读、不可重复读、虚读

脏读是所有的数据库,都必须要避免的,因为脏读会产 生错误的数据。脏读是指一个事务读取到了另一个事务没有提交的数据。

有A和B两个事务,A把其中的一条数据给修改掉了,但是这时候事务没有提交,也就是说还没有持久化到数据库,这时候在事务B里可以读取到A还没有提交的数据,这个就是脏读,如果A把操作回滚掉了,那么B得到的数据就是错误的。read uncommitted隔离级别,会产生这个问题,其它隔离级别都不会产生这个问题。

不可重复读:是指在一个事务中,两次读取同一条数据,结果发现两次读取的结果不一致,这个就是不可重复读。如果事务A开启了,然后查询了一下表中的数据,结果为RES。然后来一另外一个连接,把表中的数据改掉了,这时在事务A中再次查询,发现结果是RES1,两次的结果不一样。这个不是错误的数据,但是在某些场合,会给用户带来困扰。这里的修改,主要是指UPDATE,如果是Insert操作,会造成虚读。  不可重复读读取到的数据,不是错误的数据,这个是可以接受的。read committed隔离级别,会造成这个问题。Oracle的默认隔离级别,就是read comitted

虚读(幻读):跟不可重复读有些像,不过只有操作是INSERT的时候,才会产生虚读。在一个事务中,用户第一次统计共有多少用户的时候,结果为N,这时候刚好又有一个新用户注册,再次统计,结果发现统计的结果变成了N+1。两次读取的结果不一致。repeatable read隔离级别会产生这个问题,MySQL默认是这个隔离级别,但是MySQL在做数据库设计的时候,避免了这个问题。

从安全性上考虑: Serializable>Repeatable read>read committed>read uncommitted
从效率上考虑: read uncommitted>read committed>Repeatable read>Serializable

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Captcha Code