事务
1、事务处理(事务操作):保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改 ,整个事务回滚(rollback)到最初状态。
2、事务的ACID属性:
(1)原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
(2)一致性(Consistency) 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
(3)隔离性(Isolation) 事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
(4)持久性(Durability) 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响
开启事务
- mysql默认是自动提交,执行一句就提交一句
mysql开始事务和结束事务
-- 关闭自动提交事务,手动提交事务
set autocommit=false;
start transaction; # 或这种方式
-- 提交事务,持久化数据,永久保存在硬盘上,无法回滚
commit;
-- 出现问题执行回滚
rollback;
ACID原则
原子性(Automicity):事务是一个整体 不可拆分 要么都执行 要么都不执行
一致性(Consistency):事务执行前后数据保持一致 不能凭空消失
隔离性(Isolation):事务与事务之间相互隔离 根据不同的隔离级别 有不同的效果
持久性(Durability):通过事务最终提交的数据 将永久保存在磁盘上 无法回滚
隔离级别
隔离级别相当于数据的隔离范围。从上往下隔离级别越来越高。
数据库的4种隔离级别
事务的隔离级别:
- Read Uncommitted:读未提交 会产生脏读
- Read Commited:读已提交 会产生不可重复读
- Reapeatable Read:可重复读 会产生幻读 (默认)
- SERIALIZABLE:串行化 最安全 不会产生任何问题
脏读的概念:在一个事务中,连接A操作的未提交的数据,连接B能够读取到A操作的未提交的数据。
可重复读的概念:在同一个事务中,同一条语句读取到的数据是一样的;
不可重复读的概念:在同一个事务中,同一条语句读取到的数据是不一样的;
幻读的概念:在同一个事务中,连接A操作数据库提交事务后,连接B仍然获取不到连接A操作后的最新数据,导致连接B数据获取到的仍然是老数据,产生幻觉;
串行化:通过排队的方式,当有一个连接操作数据库时,另一个连接需要等待排队,数据安全;
事务过程
创建表,插入数据
-- 创建表
create table account(
id int primary key auto_increment comment '账户编号',
accname varchar(20) not null comment '账户名称',
money int not null comment '账户金额'
);
-- 插入数据
insert into account(accname,money) values('赵四',5000),('大拿',0);
select * from account;
设置事务的隔离级别,开启事务,操作数据,结束事务。
# 事务的隔离级别:
read-uncommitted; 读未提交 会产生脏读
read-committed; 读已提交 会产生不可重复读
repeatable-read;可重复读 会产生幻读
serializable; 串行化 最安全 不会产生任何问题
# 查看当前隔离级别
select @@transaction_isolation;
-- 设置事务的隔离级别,这个设置作用范围是表还是库
-- 事务隔离级别不会 只对某张表生效,而是对整个会话里你开启的所有事务都生效
set @@transaction_isolation = 'read-uncommitted';
开启事务,操作数据,结束事务。
# mysql中的sql语句属于自动提交的 (即直接保存在硬盘上)
# 对于需要多个sql同时执行成功最终才提交的情况 需要在事务中实现
# 开启事务 (关闭自动提交)
# set autocommit = false; 或者 set autocommit = 0 表示关闭自动提交 即通过sql执行的数据
# 将暂时保存在缓存中 等待多个sql全部执行完毕 最终确定没有问题 再提交
# 开启事务也会关闭自动提交
start transaction;
-- 操作数据
update account set money = money - 1000 where id = 1;
update account set money = money + 1000 where id = 2;
-- 结束事务:回滚或提交
rollback; # 回滚 恢复到事务执行之前的状态 事务会自动关闭
commit; # 提交 将会持久化数据 即永久保存在硬盘上 无法回滚