- 登录mysql后使用如下命令,查看存储引擎对事务的支持情况
| 事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态 |
| |
| 事务处理的原则:保证所有事务都作为 一个工作单元 来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交( commit ), |
| 那么这些修改就 永久 地保存下来;要么数据库管理系统将 放弃 所作的所有 修改 ,整个事务回滚( rollback )到最初状态。 |
| 原子性(atomicity): |
| 原子性是指事务是一个不可分割的工作单位,要么全部提交,要么全部失败回滚。 |
| |
| 一致性(consistency): |
| 根据定义,一致性是指事务执行前后,数据从一个 合法性状态 变换到另外一个 合法性状态 。这种状态是 语义上 的而不是语法上的,跟具体的业务有关。 |
| 那什么是合法的数据状态呢?满足 预定的约束 的状态就叫做合法的状态。通俗一点,这状态是由你自己来定义的(比如满足现实世界中的约束)。满足这个状态,数据就是一致的, |
| 不满足这个状态,数据就是不一致的!如果事务中的某个操作失败了,系统就会自动撤销当前正在执行的事务,返回到事务操作之前的状态。 |
| |
| 隔离型(isolation): |
| 事务的隔离性是指一个事务的执行 不能被其他事务干扰 ,即一个事务内部的操作及使用的数据对 并发 的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。 |
| |
| 持久性(durability): |
| 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是 永久性的 ,接下来的其他操作和数据库故障不应该对其有任何影响。 |
| 持久性是通过 事务日志 来保证的。日志包括了 重做日志 和 回滚日志 。当我们通过事务对数据进行修改的时候,首先会将数据库的变化信息记录到重做日志中, |
| 然后再对数据库中对应的行进行修改。这样做的好处是,即使数据库系统崩溃,数据库重启后也能找到没有更新到数据库系统中的重做日志,重新执行,从而使事务具有持久性 |
| 活动的(active) |
| 事务对应的数据库操作正在执行过程中时,我们就说该事务处在 活动的 状态。 |
| |
| 部分提交的(partially committed) |
| 当事务中的最后一个操作执行完成,但由于操作都在内存中执行,所造成的影响并 没有刷新到磁盘时,我们就说该事务处在 部分提交的 状态。 |
| |
| 失败的(failed) |
| 当事务处在 活动的 或者 部分提交的 状态时,可能遇到了某些错误(数据库自身的错误、操作系统错误或者直接断电等)而无法继续执行,或者人为的停止当前事务的执行, |
| 我们就说该事务处在 失败的 状态。 |
| |
| 中止的(aborted) |
| 如果事务执行了一部分而变为 失败的 状态,那么就需要把已经修改的事务中的操作还原到事务执行前的状态。换句话说,就是要撤销失败事务对当前数据库造成的影响。 |
| 我们把这个撤销的过程称之为 回滚 。当 回滚 操作执行完毕时,也就是数据库恢复到了执行事务之前的状态,我们就说该事务处在了 中止的 状态。 |
| |
| 提交的(committed) |
| 当一个处在 部分提交的 状态的事务将修改过的数据都 同步到磁盘 上之后,我们就可以说该事务处在了 提交的 状态。 |

| # 开启显示事务方式1 |
| BEGIN; |
| |
| # 开启显示事务方式2 |
| mysql> START TRANSACTION; |
| # START TRANSACTION 语句相较于 BEGIN 特别之处在于,后边能跟随几个 修饰符 : |
| ① READ ONLY :标识当前事务是一个 只读事务 ,也就是属于该事务的数据库操作只能读取数据,而不能修改数据。 |
| ② READ WRITE :标识当前事务是一个 读写事务 ,也就是属于该事务的数据库操作既可以读取数据,也可以修改数据。 |
| ③ WITH CONSISTENT SNAPSHOT :启动一致性读。 |
| |
| # 开启事务后进行dml操作 |
| |
| # 提交事务 |
| COMMIT; |
| |
| # 回滚事务 |
| ROLLBACK; |
| |
| # 将事务回滚到某个保存点。 |
| ROLLBACK TO [SAVEPOINT] |
| |
| # 设置保存点 |
| savepoint 保存点名称; |
| |
| # 删除保存点 |
| release savepoint 保存点名称; |
| # 查看隐式事务是否开启,默认是ON |
| SHOW VARIABLES LIKE 'autocommit'; |
| |
| # 在隐式事务中,每1条DML操作是一个独立的事务,会自动提交 |
| UPDATE account SET balance = balance - 10 WHERE id = 1; |
| |
| # 关闭自动提交 |
| # 方式1:针对于DML操作是有效的,对DDL操作是无效的 |
| SET autocommit = FALSE; |
| # 方式2: |
| SET autocommit = 0; |
| |
| # 执行dml操作 |
| UPDATE account SET balance = balance - 10 WHERE id = 1; |
| |
| # 手动提交 |
| COMMIT; |
| |
| # 回滚 |
| rollback; |
| |
| # 在autocommit为true的情况下,使用start transaction 或begin开启事务,那么DML操作就不会自动提交数据 |
| # 开启显示事务 |
| START TRANSACTION; |
| |
| # 执行dml |
| UPDATE account SET balance = balance - 10 WHERE id = 1; |
| |
| # 提交 |
| COMMIT; |
| |
| # 回滚 |
| rollback; |
| 1、数据库定义语言(DDL) |
| |
| 2、隐式使用或修改mysql数据库中的表: |
| 当我们使用ALTER USER、CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SETPASSWORD等语句时也会隐式的提交前边语句所属于的事务。 |
| |
| 3、事务控制或关于锁定的语句 |
| ① 当我们在一个事务还没提交或者回滚时就又使用 START TRANSACTION 或者 BEGIN 语句开启了另一个事务时,会 隐式的提交 上一个事务 |
| BEGIN; |
| #DDL |
| SELECT ... |
| UPDATE ... |
| #没有结束又开始下一条事务,自动隐式提交 |
| BEGIN |
| |
| ②当前的autocommit系统变量的值为OFF,我们手动把它调为ON时,也会隐式的提交前边语句所属的事务。 |
| ③使用LOCK TABLES、UNLOCK TABLES等关于锁定的语句也会隐式的提交前边语句所属的事务。 |
| |
| 4、加载数据库的语句 |
| 使用LOAD DATA语句来批量往数据库中导入数据时,也会隐式的提交前边语句所属的事务。 |
| |
| 5、关于MySQL复制的一些语句 |
| 使用START SLAVE、STOP SLAVE、RESET SLAVE、CHANGE MASTER TO等语句时会隐式的提交前边语句所属的事务。 |
| |
| 6、其他一些语句 |
| 使用ANALYZE TABLE、CACHE INDEX、CHECKTABLE、FLUSH、LOAD INDEX INTO CACHE、OPTIMIZE TABLE、REPAIR TABLE、RESET等语句也会隐式的提交前边语句所属的事务。 |
| # 默认情况下进行测试,即autocommit = TRUE时 |
| SET autocommit = TRUE; |
| |
| # 举例1: commit 和 rollback |
| USE atguigudb2; |
| # 情况1:使用BEGIN |
| # 创建表 |
| CREATE TABLE user3(NAME VARCHAR(15) PRIMARY KEY); |
| # 查看表,没有数据 |
| SELECT * FROM user3; |
| # 开启事务 |
| BEGIN; |
| INSERT INTO user3 VALUES('张三'); #此时不会自动提交数据 |
| COMMIT; |
| #开启一个新的事务 |
| BEGIN; |
| INSERT INTO user3 VALUES('李四'); #此时不会自动提交数据 |
| INSERT INTO user3 VALUES('李四'); #受主键的影响,不能添加成功 |
| ROLLBACK; |
| # 表中只有1条数据“张三” |
| SELECT * FROM user3; |
| |
| #情况2:不使用BEGIN |
| # 清空表中数据 |
| TRUNCATE TABLE user3; #DDL操作会自动提交数据,不受autocommit变量的影响。 |
| # 查看表中没有数据 |
| SELECT * FROM user3; |
| # 添加1条数据 |
| BEGIN; |
| INSERT INTO user3 VALUES('张三'); #此时不会自动提交数据 |
| COMMIT; |
| # 添加2条数据 |
| INSERT INTO user3 VALUES('李四');# 默认情况下(即autocommit为true),DML操作也会自动提交数据。 |
| INSERT INTO user3 VALUES('李四'); #事务的失败的状态 |
| # 回滚 |
| ROLLBACK; |
| # 表中有2条数据 |
| SELECT * FROM user3; |
| 扁平事务(Flat Transactions) |
| 带有保存点的扁平事务(Flat Transactions with Savepoints) |
| 链事务(Chained Transactions) |
| 嵌套事务(Nested Transactions) |
| 分布式事务(Distributed Transactions) |
| completion=0,这是默认情况。当我们执行COMMIT的时候会提交事务,在执行下一个事务时,还需要使用START TRANSACTION 或者BEGIN来开启。 |
| completion=1,这种情况下,当我们提交事务后,相当于执行了COMMIT AND CHAIN,也就是开启一个链式事务,即当我们提交事务之后会开启一个 |
| 相同隔离级别的事务。 |
| completion=2,这种情况下 COMMIT=COMMIT AND RELEASE,也就是当我们提交后,会自动与服务器断开连接。 |
| # 情况3: |
| # 清空表中数据 |
| TRUNCATE TABLE user3; |
| # 表中没有数据 |
| SELECT * FROM user3; |
| # 查看变量 |
| SELECT @@completion_type; |
| # 设置变量 |
| SET @@completion_type = 1; |
| # 插入数据 |
| BEGIN; |
| INSERT INTO user3 VALUES('张三'); |
| COMMIT; |
| # 表中有1条数据 |
| SELECT * FROM user3; |
| # 插入2条数据 |
| INSERT INTO user3 VALUES('李四'); |
| INSERT INTO user3 VALUES('李四'); # 插入失败 |
| # 回滚 |
| ROLLBACK; |
| # 表中只有1条数据“张三” |
| SELECT * FROM user3; |
| #举例2:体会INNODB 和 MyISAM |
| # 创建2张表,并指定不同存储引擎 |
| CREATE TABLE test1(i INT) ENGINE = INNODB; |
| |
| CREATE TABLE test2(i INT) ENGINE = MYISAM; |
| |
| #针对于innodb表 |
| # 插入1条数据,并回滚 |
| BEGIN |
| INSERT INTO test1 VALUES (1); |
| ROLLBACK; |
| # 表中没有数据 |
| SELECT * FROM test1; |
| |
| #针对于myisam表:不支持事务 |
| # 插入1条数据,并回滚 |
| BEGIN |
| INSERT INTO test2 VALUES (1); |
| ROLLBACK; |
| # 表中有1条数据 |
| SELECT * FROM test2; |
| # 创建表 |
| CREATE TABLE user3(NAME VARCHAR(15),balance DECIMAL(10,2)); |
| # 添加1条数据 |
| BEGIN |
| INSERT INTO user3(NAME,balance) VALUES('张三',1000); |
| COMMIT; |
| # 查看为1000 |
| SELECT * FROM user3; |
| # 减少200 |
| BEGIN; |
| UPDATE user3 SET balance = balance - 100 WHERE NAME = '张三'; |
| UPDATE user3 SET balance = balance - 100 WHERE NAME = '张三'; |
| #设置保存点 |
| SAVEPOINT s1; |
| # 加1 |
| UPDATE user3 SET balance = balance + 1 WHERE NAME = '张三'; |
| #回滚到保存点 |
| ROLLBACK TO s1; |
| # 查询为800 |
| SELECT * FROM user3; |
| #回滚操作 |
| ROLLBACK; |
| # 回滚为1000 |
| SELECT * FROM user3; |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
2021-06-21 vue3.0入门(五):vite构建vue项目
2021-06-21 vue3.0入门(四):组件