一、什么是ACID

1、原子性(Atomicity)

原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

2、一致性(Consistency)

事务前后数据的完整性必须保持一致。

3、隔离性(Isolation)

事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

4、持久性(Durability)

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

二、例子

1、原子性

针对同一个事务
事务 - 图1

这个过程包含两个步骤

A: 800 - 200 = 600
B: 200 + 200 = 400
原子性表示,这两个步骤一起成功,或者一起失败,不能只发生其中一个动作

2、一致性(Consistency)

针对一个事务操作前与操作后的状态一致

事务 - 图2

操作前A:800,B:200
操作后A:600,B:400

一致性表示事务完成后,符合逻辑运算
无论怎么转,最后的值一定是1000

3、持久性(Durability),事务一旦提交,不可逆

表示事务结束后的数据不随着外界原因导致数据丢失
操作前A:800,B:200
操作后A:600,B:400
如果在操作前(事务还没有提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为
A:800,B:200
如果在操作后(事务已经提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为
A:600,B:400
事务还没有提交,

4、隔离性(Isolation)

4.1、针对多个用户同时操作,主要是排除其他事务对本次事务的影响

事务 - 图3
两个事务同时进行,其中一个事务读取到另外一个事务还没有提交的数据,B
事务 - 图4

4.2、事务的隔离级别

1、脏读

指一个事务读取了另外一个事务未提交的数据。
事务 - 图5

2、不可重复读:

在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误,只是某些场合不对)页面统计查询值
事务 - 图6
点击生成报表的时候,B有人转账进来300(事务已经提交)
事务 - 图7

3、幻读(虚读)

是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。(一般是行影响,多了一行)
事务 - 图8

4.3、数据库四种隔离级别

数据库 mysql 默认是:可重复读;oracle默认是:读已提交

set transaction isolation level 设置事务隔离级别
select @@tx_isolation 查询当前事务隔离级别

描述

Read uncommitted 最低级别,以上情况均无法保证。(读未提交)
Read committed 可避免脏读情况发生(读已提交)。
Repeatable read 可避免脏读、不可重复读情况的发生。(可重复读)
Serializable 可避免脏读、不可重复读、虚读情况的发生。(串行化)

4.4、demo

4.4.1、mysql设置隔离级别、开启事务

  1. -- 设置隔离级别 可重复读
  2. SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
  3. -- 查询数据库隔离级别
  4. select @@tx_isolation
  5. -- 设置不自动提交
  6. set autocommit = 0;
  7. -- 开始事务
  8. start TRANSACTION
  9. select * from userlist;
  10. -- 提交
  11. COMMIT;

4.4.2、批量创建数据的存储过程

  1. DROP TABLE IF EXISTS `fds_test`;
  2. CREATE TABLE `fds_test` (
  3. `id` int(11) NOT NULL,
  4. `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  5. `age` int(3) NOT NULL,
  6. `job` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  7. `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  8. `create_time` datetime(0) NULL DEFAULT NULL,
  9. `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  10. `city` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  11. PRIMARY KEY (`id`) USING BTREE
  12. ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  1. CREATE DEFINER=`root`@`%` PROCEDURE `batch_data_fds_test`(IN startNum INT, endNum INT)
  2. BEGIN
  3. SET @count = startNum;
  4. WHILE startNum <= @count <= endNum DO
  5. INSERT INTO fds_test VALUES (@count, CONCAT('fds', @count), @count, 'coding', '江苏省苏州市吴江区', SYSDATE(), '备注', '苏州');
  6. SET @count = @count + 1;
  7. END WHILE;
  8. END