事务

事务控制语句:

  • BEGIN 或 START TRANSACTION 显式地开启一个事务;

  • COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;

  • ROLLBACK 也可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;

  • SAVEPOINT identifier,SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;

  • RELEASE SAVEPOINT identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;

  • ROLLBACK TO identifier 把事务回滚到标记点;

  • SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

事务并发下出现的问题

通常事务并发会出现几种现象:1.脏读;2.不可重复读;3.幻读。

  • 脏读

一个事务 A 读取了另一个并行事务 B 未最终提交的写数据, 那事务A的这次读取就是脏读。

  • 不可重复读

假设“脏读”问题完全解决了,那就意味着事务中每次读取到的数据都是“持久性”的数据(被别的事务最终“提交/回滚”完成后的数据)。

但是解决了脏读问题, 只是能保证你在事务中每次读到的数据都是持久性的数据而已!

如果在 一个事务 中多次读取同一个数据,正好在两次读取之间,另外一个事务确实已经完成了对该数据的修改并提交,那问题就来了,可能会出现 多次读取结果不一致 的现象,这种现象也就被称为不可重复读:

A事务读取了B事务已经提交的更改(或删除)数据。比如A事务第一次读取数据,然后B事务更改该数据并提交,A事务再次读取数据,两次读取的数据不一样。将数据库事务隔离级别设为repeatable read即可

  • 幻读

事务 A 在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务 B 执行了新增数据的操作并提交后,这个时候事务 A 读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,这种现象就称为幻读:

A事务读取了B事务已经提交的新增数据。注意和不可重复读的区别,这里是新增,不可重复读是更改(或删除)。这两种情况对策是不一样的,对于不可重复读,只需要采取行级锁防止该记录数据被更改或删除,然而对于幻读必须加表级锁,防止在这个表中新增一条数据(PS:对于锁的问题请自行查找或关注我的后续文章)。
当然,也可以将数据库事务隔离级别设为serializable,但一般不这样做,因为该策略是完全阻塞的,将对数据库的访问完全序列化,并发性能最差。
如果A事务只进行读操作,不进行写操作,将数据库事务隔离级别设为repeatable read,并用start transaction with consistent snapshot开启事务,同时进行快照读,也可以防止幻读现象(因为在可重读策略下,不是开启事务就建立快照点,而是在第一次查询时建立快照点)
丢失更新

第一类丢失更新:A事务提交时,把已提交的B事务的数据覆盖掉。

第二类丢失更新:A事务回滚时,把已提交的B事务的数据覆盖掉。

第一类
在这里插入图片描述
理论库存是7个,但现在剩余8个;
第二类
在这里插入图片描述
理论库存是9个,但现在剩余10个;(这是抄的 抄的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值