事务
为什么要有事务
- 事务广泛的运用于订单系统、银行系统等多种场景
- 例如:A用户和B用户是银行的储户,现在A要给B转账500元,那么需要做以下几件事:
- 检查A的账户余额>500元
- A账户中扣除500元
- B账户中增加500元
- 正常的流程走下来,A账户扣了500,B账户加了500,皆大欢喜。那如果A账户扣了钱之后,系统出故障了,A白白损失了500,而B也没有收到本该属于他的500。以上的案例中,隐藏着一个前提条件:A扣钱和B加钱,要么同时成功,要么同时失败。事务的需求就在于此。
- 检查A的账户余额>500元
- 事务(Transaction)是并发控制的基本单位。所谓事务,它是一个操作序列,这些操作必须同步,如果执行就都执行,如果不执行就都不执行,它是一个不可分割的工作单位。例如,银行转账工作:从一个账号扣款并使另一个账号增款,这两个操作必须同步。所以,应该把他们看成一个事务。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性。
- 一旦开启了事务之后,那么对数据库的更新操作不会立即影响到源数据库,只有在成功之后执行提交的操作,才会将变化提交给源数据库
事务的四大特性(简称 ACID)
- 1、原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,是同步的,如果执行就全部执行,如果不执行,就全部不执行。
- 2、一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果一致。
- 3、隔离性(lsolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。
- 4、持久性(Durability):对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。
事务使用注意点
- 要求:表的引擎类型必须是innodb类型才可以使用事务。
- 查看表的创建语句,可以看到 engine=innodb:
- 修改数据的命令会触发事务,包括insert、update、delete
默认打开一个终端是开启事务的,这个事务会自动的进行提交。 - 注意:当手动的开始一个事务以后,必须手动的进行提交,否则刚刚的操作是不会反应到数据库中的。
开启事务 begin:
- 开启事务后执行修改命令,变更会维护到本地缓存中,而不维护到物理表中,开启事务以后所有的操作都不要立即反应到数据表上。
- 接下来修改数据
- 重新打开一个终端,查看表的内容
提交事务 commit
- 将缓存中的数据变更维护到物理表中,现在我们在开启事务的终端窗口,进行commit;
- 这样在没有开启事务的那个连接中,也就可以看到数据信息了。
回滚事务 rollback:放弃缓存中变更的数据
- 我们发现数据消息就没有了。但是,当我们再插入数据信息的时候,数据表的id信息,不在是20了,因为20已经用了。
- 实际在写代码的时候如下:
事务
- 可以通过 begin 手动开启事务
- 一旦开启事务之后,对于时局的更新操作,不会立即影响到原数据库,等到所有的 sql 执行成功之后,手动 commit(提交)才会影响到原数据库,没有手动开启事务的时候,事务也是开启的,不过提交操作是自动执行
- 如果大批量数据更新的时候,手动开启事务的效率是怎么样的呢?
- 大批量更新数据的时候需要手动开启事务。
- 提高更新的效率,更加安全
事务管理:
- 事务处理机制在程序开发过程中有着非常重要的作用,它可以使整个系统更加安全,保证在同一个事务中的操作具有同步性。
事务的概念
- 现实生活中,人们经常会进行转账操作,转账可以分为两个部分来完成,转入和转出,只有这两个部分都完成才认为转账成功。在数据库中,这个过程是使用两条语句来完成的,如果其中任意一条语句出现异常没有执行,则会导致两个账户的金额不同步,造成错误。
- 为了防止上述情况的发生,mysql中引入了事务,所谓事务就是针对数据库的一组操作,它可以由一条或多条mysql语句组成,同一个事务的操作具备同步的特点,如果其中有一条语句无法执行,那么所有的语句都不会执行,也就是说,事务中的语句要么都执行,要么都不执行。
- 在数据库中使用事务时,必须先开启事务,开启事务的语句如下:
- start transaction;
- 事务开启之后就可以执行SQL语句,SQL语句执行成功后,需要使用相应语句提交事务。提交事务的语句如下:
- commit;
- 需要注意的是:在mysql中直接书写的sql语句都是自动提交的,而事务中的操作语句都需要使用commit语句手动提交,只有事务提交后其中的操作才会生效。
- 如果不想提交当前事务还可以使用相关语句取消事务(也称回滚),回滚语句如下:
- rollback;
- 需要注意的是:rollback语句只能针对未提交的事务执行回滚操作,已提交的事务是不能回滚的。
通过转账的案例来演示如何使用事务:
准备工作:
-
开启事务,然后再通过update语句将a账户的100元转给b账户,最后提交事务:
-
提交事务
-
通过事务成功地完成了转账功能。
-
需要注意的是:上述的两条update语句中如果任意一条语句出现错误就会导致事务不会提交,这样一来,如果在提交事务之前出现异常,事务中未提交的操作就会被取消,因此就可以保证事务的同步性。
事务有很严格的定义,它必须同时满足4个特性:
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔离性(Isolation)
- 持久性(Durability)
也就是人们俗称的ACID标准。
- 原子性:
- 原子性是指一个事务必须被视为一个不可分割的最小工作单元,只有事务中所有的数据库操作都执行成功,才算整个事务执行成功,事务中如果有任何一个SQL语句执行失败,已经执行成功的SQL语句也必须撤销,数据库的状态退回到执行事务前的状态。
- 一致性:
- 一致性是指事务将数据库从一种状态转变为下一种一致的状态。例如:在表中有一个字段为姓名,具有唯一约束,即姓名不能重复,如果一个事务对姓名进行了修改,使姓名变得不唯一了,这就破坏了事务的一致性要求,如果事务中的某个动作失败了,系统可以自动摊销事务,返回初始化的状态。
- 隔离性:
- 隔离性还可以称为并发控制、可串行化,锁等,当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
- 持久性:
- 事务一旦提交,其所做的修改就会永久保存到数据库中,即使数据库发生故障也不应该对其有任影响。需要注意的是,事务的持久性不能做到100%的持久,只能从事务本身的角度来保证永久性,而一些外部原因导致数据库发生故障,如硬盘损坏,那么所有提交的数据可能都会丢失。