事务简介

事务是一组操作的集合,是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或者撤销操作请求,即要么同时成功,要么同时失败

  1. 开启事务(手动)

  2. 处理事务 (手动)

  3. 提交事务(如果异常,回滚事务)(也是手动)

每一条sql语句都是一个事务

对于Mysql而言,事务是默认自动提交的

我们执行CRUD时,语句一旦执行完,数据就提交到数据库了。

事务操作

1
2
3
4
5
6
7
// 转账操作的必要准备
create table account(
id int auto_increment primary key comment '主键ID',
name varchar(20) comment '姓名',
money int comment '余额'
)comment '账户表';
insert into account(id, name, money) VALUES (null,'张三',2000),(null,'李四',2000);
  • 查看/设置事务提交方式

    隐形控制事务

    select @@autocommit; //查询你现在的提交方式

    set @@autocommit=0; //设置为手动提交

    0 代表自动提交 1代表手动提交

    显性控制事务

    如果开启,则表示你是手动控制

    start transaction

    begin

  • 提交事务

    commit;

  • 回滚事务

rollback;

  • 总结:

    1. 自动提交就是同步更新,手动提交就是干完后提交更新

    2. 可以将事务与git推送到github相联系,手动提交就是你先在自己的本地仓库中进行改进,然后再推送到远程仓库中

    3. 在实际情况中数据库的操作改变是不仅仅只有一个语句那么简单,事务是一堆Mysql语句的集合,有时候Mysql语句的加入和改变直接代表则某个功能的更新增加,同时这个更加方便测试

    4. commit相当于存放到本地仓库中,rollback相当于把本地仓库中的内容退回来


事务的四大特性(ACID)

  1. 原子性(Atomicity)

    事务时不可分割的最小操作单元,要么全部成功要么全部失败

  2. 一致性(Consistency)

    事务完成时,必须使所有的数据都保持一致状态

  3. 隔离性(Isolation)

    数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行

  4. 持久性(Durability)

    事务一旦提交或回滚,他对数据库中的数据改变就是永久的


并发事务引发的问题

​ 严重性: 脏读>不可重复读>幻读

  • 脏读

    一个事务读到另外一个事务还没有提交的数据

  • 不可重复读

    一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读

    例如事务A与事务B,事务A先对数据库进行第一次查询,在第二次查询前事务B进行了更新,就会实现两次查询到的数据不同(两次查询语句相同)

  • 幻读

    一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了幻影

    例如事务A与事务B,如果事务A先对数据库进行第一次查询,发现没有数据存在,然后事务B对数据库进行了Insert,再然后事务A对数据进行了插入(因为一开始自认为没有),但是发现其实已经被B捷足先登了,但是如果你再去查询是否存在的问题时,你会发现数据行还是没有,就像出现了幻觉。(这是因为我们已经解决了不可重复读的问题了,事务进行中展示数据并不会改变)

    (像极了你问她昨天还没男朋友的,今天打算表白,然后发现昨天凌晨她找了个男朋友,你问她她却说她还是单身,Nima..)


事务隔离级别

用来解决并发事务问题

  • 读未提交 (read uncommitted),指事务还未提交,它做的变更就能被其他事务看到
  • 读提交(read committed),指事务提交后,其他事务才能看到它做的变更
  • 可重复读(Mysql默认)(repeatable read),指事务执行过程中看到的数据跟它启动时看到的数据相同
  • 串行化(serializable),通过对记录写上锁,另一事务的操作必须等前一事务的完成才能进行
  • 隔离级别:串行化>可重复读>读提交>读未提交

从文字上也可以很清楚的明白每个级别可以处理的问题

  • 读未提交,会出现脏读,不可重复读,幻读
  • 读提交,会出现不可重复读,幻读
  • 可重复读,会出现幻读
  • 串行化,啥都不会出现

数据安全性和性能是成反比的

不同的数据库厂商对 SQL 标准中规定的 4 种隔离级别的支持不一样,有的数据库只实现了其中几种隔离级别,我们讨论的 MySQL 虽然支持 4 种隔离级别,但是与SQL 标准中规定的各级隔离级别允许发生的现象却有些出入

MySQL 在「可重复读」隔离级别下,可以很大程度上避免幻读现象的发生(注意是很大程度避免,并不是彻底避免),所以 MySQL 并不会使用「串行化」隔离级别来避免幻读现象的发生,因为使用「串行化」隔离级别会影响性能。

查看事务的隔离界别

select @@transaction_isolation

设置事务隔离级别

set [session|global] transaction isolation level{read unmommited|read committed|repeatable read| serializable}

session- 当前窗口有效 global-所有窗口有效

总结

事务总体感觉更偏向于实践,但是基础篇中更偏向理论了解

NX给的链接,感谢!

NX