日常生活中,经常涉及到事务。事务是数据库操作的基本单位,它代表了一系列操作,这些操作要么全部成功执行,要么全部不执行,以确保数据的一致性和完整性。
比如转账业务:现在张三和李四都各有200元,张三要给李四转账100元,那么转账成功后,张三的金额为100元,李四的金额为300元,该事务在数据库中的操作需要执行两条SQL命令,这两条SQL命令必须同时成功或失败 。
update act set money=100 where id = 1;
update act set money=300 where id = 2;
但仅执行这两条基本SQL命令是无法实现的,必须要引入SQL事务。
一、什么是事务?
事务本身是一个完整的业务流程,是不可再分的工作单元。
事务只和DML(增删改)语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同。
二、事务的四大特征(ACID)
1、原子性
原子性指一个事务是一个不可分割的工作单位,其中的操作要么都成功,要么都失败,不可能出现第三种情况。
本质上是通过MySQL底层的日志来实现的。
2、持久性
持久性指实物一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
用上述示例简单解释一下,现在事务成功提交,即张三向李四转账成功后,张三金额为100元,李四金额为300元。如果此时MySQL出现某些故障,张三和李四的金额也不会回到转账前的各为200元的状态,因为事务已经提交,任何操作和故障都不会影响到它。
3、隔离性
隔离性指事物内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
仍然是上述示例简单解释,假如现在张三向李四转账100元,王五又向张三转账100元,直接让王五向李四转账100元,张三账户不变是符合逻辑的吗?答案一定是不,因为事务和事务之间是隔离的,互不干扰的。
4、一致性
事务执行的结果必须是使数据库从一个一致状态变到另一个一致状态。
依旧是上述示例,张三向李四成功转账100元后,虽然张三和李四的金额变了,但相加起来的总金额是不变的,仍是400元。
三、MySQL如何实现事务?
首先,我们先实现张三给李四转账100元。
- 无事务版并且完成转账:
update act set money=100 where id = 1;
update act set money=300 where id = 2;
以上的写法并没有添加事务,那么一旦在SQL执行过程中出现了问题,就会出现意料之外的错误,这是不可忍受的。
比如第一条SQL语句成功实现,但第二条SQL语句可能由于id错误导致失败,这样就不能保证一致性,导致错误发生。
为解决以上问题,我们可以添加事务,开启事务之后,能成功保证这两条SQL语句同时成功或失败。
(1)开启事务
start transaction;
(2)实现转账业务
update act set money=100 where id = 1;
update act set money=300 where id = 2;
(3)提交事务
commit;
运行,转账成功:
事务的优点在于:SQL在执行的过程中一旦出现问题,可以进行回滚回到原来的状态。
(5)事务的回滚
rollback;
比如第二条SQL语句中的id出现错误,即使第一条SQL语句可以正常执行,但由于我们添加了事务的回滚,所以会回到最初的状态,即转账失败。