【十二】MySQL数据库之事物

发布时间 2023-06-30 20:52:04作者: Chimengmeng

【十二】MySQL数据库之事物

事务

【一】什么是事务?

  • 事务是MySQL的一种机制
    • 每开启一个事务
    • 都可以往里放入一系列的SQL语句。
  • 事务是单个逻辑工作单位执行的一系列操作
    • 要么全执行
    • 要么全不执行
  • 每开一个事务
    • 相当于给数据库拍了一张快照
    • 这意味着在提交之前可以回滚
    • 在事务中可以设置多个保存点
    • 然后可以进行回滚到每个保存点
  • 我们默认为每条sql开启事务
    • 并且会在本条sql执行完毕后自动执行commit提交
    • 直接用 SET 来改变 MySQL 的自动提交模式
    • 手动开启的事务里默认不会自动提交。
  • 结束事务可以使用commit和rollback
    • 结束事务会释放事务中所有的锁

【二】事务有哪些特性?

我们可以拿发起一笔转账作为例子来诠释事务的特性

(A)原子性:
  • 事务内部的sql语句是一个不可分割的整体
    • 这一系列的sql语句如果有一条运行失败
    • 则整体都运行失败
  • 比如转账行为(指转账方金额减少和接收方金额增加)
    • 只可能全执行成功或全执行失败,
(C)一致性:
  • 事务执行前后的状态保持一致
    • 和原子性紧密相关
    • 比如张三和李四都有500元的余额
    • 他们余额的总数是1000元
    • 然后开启了一个转账事务
    • 张三给李四转了100元以后
    • 他们各自的余额发生了变化
    • 但他们的总金额仍然保持不变。

另外,在事务发生的前后,数据类型也应该保持一致。

(I)隔离性:
  • 多个事务并发运行
    • 但彼此之间互不影响
    • 比如转账时如果A和B同时各开一个事务给C转账
    • 事务2的B先转账成功
    • 但此时事务1中的A看不到B转账成功的信息
    • 但A转账完
    • C能同时收到A和B的转账
(D)持久性:
  • ⼀个事务被提交(commit)之后
    • 它对数据库中数据的改变是持久的
    • 即使数据库发⽣故障也不应该对其有任何影响。

小实验:验证事务的一致性

准备表:
create table employee(
id int primary key auto_increment,
name varchar(20) not null,
age int(3) unsigned not null default 20
);

insert into employee(name) values
('歪歪'),
('丫丫'),
('丁丁'),
('星星'),
('格格'),
('张野'),
;
update employee set age = 18 where id <=3;
实验:
步骤1 start transaction;select * from employee where name = "dream"; -- 对应的age = 18 start transaction;select * from employee where name = "dream"; -- 对应的age = 18
步骤2 update employee set age=age+1 where name = "egon";commit; -- 修改egon的年龄为19岁,并提交select * from employee where name = "dream"; -- 对应的age变为19
步骤3 -- 在事务二commit之后,重新查询,发现对应的age 仍为18 select * from employee where name = "dream";
步骤4 -- 虽然看到的age仍为18,但因为事务的一致性原则,其实此处的修改是在age=19的基础上进行的update employee set age=age+1 where name = "dream"; -- 查看到age变为20select * from employee where name = "dream";
步骤5 commit;select * from employee where name = "dream"; -- age =20

【三】MySQL开启事务的三种方式

1、隐式开启,隐式提交(默认)

  • 默认情况下,你每敲一条SQL语句,都会开启一个事务。
    • 这条语句一运行完,会自动帮你commit提交
    • 所以平时我们使用update语句修改数据库,都会自动提交。

2、显式开启,显示提交

  • 使用代码 start transaction或者简写为begin。
  • 这样你所写的事务就不会自动触发commit提交
    • 你可以选择手动commit 提交或是rollback回滚。
  • 注意点:
    • 无论是commit还是 rollback,该事务都会结束

3、显示开启,隐式提交

  • 设置参数
Set session autocommit =0
  • 这样设置完,就不会自动提交

总结:

  • MYSQL 默认为每条sql开启事务
    • 并且会在本条sql执行完毕后自动执行commit提交
    • 若想设置手动提交,有两种方式
方式一:直接用 SET 来改变 MySQL 的自动提交模式(下述设置均为会话级别的设置):
SET AUTOCOMMIT=0 禁止自动提交
SET AUTOCOMMIT=1 开启自动提交
方式二: 手动开启的事务里默认不会自动提交
  • 手动开启的事务里默认不会自动提交
    • 所以我们可以将要执行的sql语句放在我们自己手动开启的事务里
start transaction;
update test.t1 set id=33 where name = "jack";
commit;

注意:

​ 这种方式在当你使用commit或者rollback后,事务就结束了

​ 再次进入事务状态需要再次start transaction