一、事务
- 事务的概念
事务(Transaction)是一个操作序列,该序列中的多个操作要么都做,要么都不做 是MySQL5.5之后的存储引擎所支持。
事务,就是把一堆事情绑在一起做,都成功了才算完成,否则就恢复之前的样子 举例:银行ATM取钱,扣款成功后突然大停电,吐钱的操作还没做,这时候ATM机就要恢复到没取钱时候的状态,否则钱扣了还没拿到手,会发生错误。
事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所做的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。 事务的结束有两种,当事务中的所有步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消之前到事务开始时的所有操作。 - 事务的特点( 简称 ACID)
a. 原子性(atomicity)
原子是自然界中最小的颗粒,具有不可再分的特点,事务中的所有操作可以看作是一个原子(事务是数据库的逻辑工作单位),要么全部执行,要么全不执行.
b. 一致性(consistency)
事务执行的结果必须要保证数据库中数据的一致性
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态 。
c.隔离性(isolation)
隔离性指各个事务的操作是互不干扰的,即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
d.持久性(durability)
持久性也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响.
二、事务的控制
1.创建一个库 test1
2.创建一张表account(id账号主键唯一,username账号名,balance金额)
3.插入数据
--创建表account
create table account(
id int(8) primary key auto_increment,
username varchar(30),
balance double
);
–插入数据
insert into account(username,balance) values('张三',2000),('李四',2000)
–查询数据
select * from account;
1.开启事务
语法:start | begin transaction开启一个新的事务
--例如:开启新事务,完成张三给李四转账200
--开启新事务,完成张三给李四转账200
start transaction;
update account set balance=balance-200 where username='张三';
update account set balance=balance+200 where username='李四';
注意:使用start transaction 开启一个新事务后,该事务不会自动提交,必须手动提交。
2.提交事务
语法:commit
start transaction;
update account set balance=balance-200 where username='张三';
update account set balance=balance+200 where username='李四';
commit;
3.回滚事务
语法:rollback
注意:开启的事务,未提交时候可以回滚。
start transaction;
update account set balance=balance-200 where username='张三';
update account set balance=balance+200 where username='李四';
rollback;
三、事务的隔离级别
事务的隔离级别用于决定如何控制并发用户读写数据的操作,事务的隔离级别由低到高分为:
- read uncommitted
指:读取未提交的数据内容
- 事物A和事物B,事物A未提交的数据,事物B可以读取到
- 这里读取到的数据叫做“脏数据”
- 这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别
- read committed
指:读取提交的数据,该隔离级别下,所有事务只能看到其他事务已经提交的数据,该隔离级别解决了脏读的问题
- 事物A和事物B,事物A提交的数据,事物B才能读取到
- 这种隔离级别高于读未提交
- 换句话说,对方事物提交之后的数据,我当前事物才能读取到
- 这种级别可以避免“脏数据”
- 这种隔离级别会导致“不可重复读取”
- Oracle默认隔离级别
- repeatable read
指:(可重复读)是MySQL默认的隔离级别
- 事务A和事务B,事务A提交之后的数据,事务B读取不到
- 事务B是可重复读取数据
- 这种隔离级别高于读已提交
- 换句话说,对方提交之后的数据,我还是读取不到
- 这种隔离级别可以避免“不可重复读取”,达到可重复读取
- 比如1点和2点读到数据是同一个
- MySQL默认级别
- 虽然可以达到可重复读取,但是会导致“幻像读”
幻读
幻读是指当事务不是独立执行时发生的一种现象。
SQL标准这么定义幻读,在两个连续的查找之间一个并发的修改事务修改了查询的数据集,导致这两个查询返回了不同的结果。
4.serializable
(可串行化)该隔离级别是最高的,同时花费也是最高的,性能最低,一般很少用。因为在该隔离级别下,事务按着顺序执行。
- 事务A和事务B,事务A在操作数据库时,事务B只能排队等待
- 这种隔离级别很少使用,吞吐量太低,用户体验差
- 这种级别可以避免“幻像读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行,而不并发