mysql事务保证数值不小于0_Mysql(三)——事务的特性、事务并发、事务读一致性问题…

  • Post author:
  • Post category:mysql


让它全部失败呢?这个时候我们必须要回滚。

原子性,在 InnoDB 里面是通过 undo log 来实现的,它记录了数据修改之前的值(逻

辑日志),一旦发生异常,就可以用 undo log 来实现回滚操作。

第二个,一致性,consistent,指的是数据库的完整性约束没有被破坏,事务执行的

前后都是合法的数据状态。比如主键必须是唯一的,字段长度符合要求。

除了数据库自身的完整性约束,还有一个是用户自定义的完整性。

比如说转账的这个场景,A 账户余额减少 1000,B 账户余额只增加了 500,这个时

候因为两个操作都成功了,按照我们对原子性的定义,它是满足原子性的, 但是它没有

满足一致性,因为它导致了会计科目的不平衡。

还有一种情况,A 账户余额为 0,如果这个时候转账成功了,A 账户的余额会变成

-1000,虽然它满足了原子性的,但是我们知道,借记卡的余额是不能够小于 0 的,所以

也违反了一致性。用户自定义的完整性通常要在代码中控制。

第三个,隔离性,Isolation,我们有了事务的定义以后,在数据库里面会有很多的

事务同时去操作我们的同一张表或者同一行数据,必然会产生一些并发或者干扰的操作,

那么我们对隔离性的定义,就是这些很多个的事务,对表或者行的并发操作,应该是透

明的,互相不干扰的。通过这种方式,我们最终也是保证业务数据的一致性。

最后一个叫做持久性,Durable,事务的持久性是什么意思呢?我们对数据库的任意

的操作,增删改,只要事务提交成功,那么结果就是永久性的,不可能因为我们系统宕

机或者重启了数据库的服务器,它又恢复到原来的状态了。这个就是事务的持久性。

持久性怎么实现呢?数据库崩溃恢复(crash-safe)是通过什么实现的?

持久性是通过 redo log 和 double write 双写缓冲来实现的,我们操作数据的时候,

会先写到内存的 buffer pool 里面,同时记录 redo log,如果在刷盘之前出现异常,在

重启后就可以读取 redo log 的内容,写入到磁盘,保证数据的持久性。

当然,恢复成功的前提是数据页本身没有被破坏,是完整的,这个通过双写缓冲

(double write)保证。

原子性,隔离性,持久性,最后都是为了实现一致性。

1.5 数据库什么时候会出现事务

无论是我们在 Navicat 的这种工具里面去操作,还是在我们的 Java 代码里面通过

API 去操作,还是加上@Transactional 的注解或者 AOP 配置,其实最终都是发送一个

指令到数据库去执行,Java 的 JDBC 只不过是把这些命令封装起来了。

我们先来看一下我们的操作环境。版本(5.7),存储引擎(InnnoDB),事务隔离

级别(RR)。

selectversion();

show variables like’%engine%’;

showglobal variables like “tx_isolation”;

执行这样一条更新语句的时候,它有事务吗?

update student set sname = ‘猫老公 111’ where id=1;

实际上,它自动开启了一个事务,并且提交了,所以最终写入了磁盘。

这个是开启事务的第一种方式,自动开启和自动提交。

InnoDB 里面有一个 autocommit 的参数(分成两个级别, session 级别和 global

级别)。



版权声明:本文为weixin_39664995原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。