关于MySQL中的事务、提交(commit)、回滚(rollback)
事务:数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。
摘要:
一个数据库事务通常包含了一个序列的对数据库的读/写操作。
它的存在包含有以下两个目的:
1.为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
2.当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。
当事务被提交给了DBMS(数据库管理系统),则DBMS需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要被回滚,回到事务执行前的状态;
同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的运行。
事务性质
数据库事务拥有以下四个特性,习惯上被称之为ACID特性。
- 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
- 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
- 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
- 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。
关于事务的一些术语
- 开启事务:Start Transaction
- 事务结束:End Transaction
- 提交事务:Commit Transaction
- 回滚事务:Rollback Transaction
和事务相关的两条重要的SQL语句(TCL)
- commit:提交
- rollback:回滚
事务开启的标志?事务结束的标志?
开启标志:
- 任何一条DML语句(insert、update、delete)执行,标志事务的开启
结束标志(提交或者回滚):
- 提交:成功的结束,将所有的DML语句操作历史记录和底层硬盘数据来一次同步
- 回滚:失败的结束,将所有的DML语句操作历史记录全部清空
最初校园的老师讲事务的时候喜欢讲这么一个例子:你向别人汇款1000元,你的账户金额减少1000,对方的账户金额增加1000元视为该过程成功,其他情况比如你的账户金额减少1000,对方并未增加视为失败,事务回滚,该事物执行的过程是2步,(1)你的金额减少 (2)对方的金额增加 若(1)与(2)同时成功,执行commit,若未同时成功执行rollbak,回滚到未进行任何操作的状态
mysql可以回滚的几个设置:
一、配置事务,两个方法,(1)修改配置文件 (2)设置环境变量
MySQL客户端shell关于“自动提交”和“事务”的参数是autocommit,默认值是1,即默认开启自动提交,事务不开启。
所以当你每次使用insert、delete、update等语句的时候,数据表实际就会完成更改。
修改配置则有两种方式。
查看 MySQL 客户端的事务提交方式命令:
select @@autocommit; 或者 show variables like 'autocommit';
修改 MySQL 客户端的事务提交方式为手动提交命令:
set @@autocommit = 0; 或者 set @@autocommit = 'off';
1 修改my.cnf配置文件
[mysqld]
# 新增如下内容,预连接选项
init_connect='SET autocommit=0'
注意:
连接mysql用户的权限不能大于启动mysql的用户的权限,不然init_connect='SET autocommit=0’根本不会启作用,也不会报任何错误
2 设置环境变量
此种方式开启的事务仅仅对本次连接和本次连接开启的客户端shell有效,关闭后再开启则恢复配置文件所定义的或者默认配置的状态。
先通过以下两种方式查询
然后在另一个查询窗口中
不同的查询窗口看到的结果是不同的,原因是:第一个窗口的结果off是自己设置的
第二个结果是默认的,也就是说回应了前面提到的【此种方式开启的事务仅仅对本次连接和本次连接开启的客户端shell有效】
当autocommit的value值是off的情况下,执行DML语句,需要执行commit语句,运行的dml才能真正的生效,不然仅在该查询窗口中执行,其他窗口的查询结果依然是未执行dml语句前的值,
注意:
直接退出客户端,事务中的变更不会默认保存 --【此种方式开启的事务仅仅对本次连接和本次连接开启的客户端shell有效】
3、直接开始事务
除了配置开启事务,也可以直接使用start transaction开启事务。
注意:
这种方式在当你使用commit或者rollback后,事务就结束了
再次进入事务状态需要再次start transaction
上面是最初的数据
然后执行start transaction;语句
然后执行上面update语句后,查询结果如上图
执行rollbak;语句后
又回到最初的数据状态
总结:在上面提到三种的可以回滚的方法中,方法2与方法3是已经验证过