事务是个啥?
事务(Transaction)一般是指要做的或所做的事情。数据库事务(Database Transaction)是由SQL语句组成的逻辑处理单元。一个事务是一条SQL语句或一组SQL语句,不管是一条还是一组,都是可以一个事务。事务中的SQL语句就是一个整体,其中的SQL语句要么都执行,要么都不执行。
MySQL事务常用于操作量大,复杂性高的数据,避免因误操作而出现数据信息异常,确保了数据的一致性和完整性。
事务的四大特性(ACID)
1.原子性[不可分割性](Atomicity):一个事务中的所有操作,要么全部执行,要么全部不执行,不存在只执行部分语句情况。若事务在执行过程中出现错误,则会被回滚(Rollback)到事务开始前的状态,并不会对数据进行实际更改。
2.一致性(Consistency):事务开始前,数据库处于一个一致性状态,事务结束后,数据库必须也处于一致性状态。例如:银行转账后,两个账户金额之和与转账前相同。
3.隔离性[独立性](Isolation):避免一个事务执行时被其他事务所干扰。即一个事务中的操作对其他事务是隔离的,各个事务之间不能互相干扰。
4.持久性(Durability):一个事务提交之后,对数据库的修改就是永久的,即使服务宕掉也可以进行数据恢复。
提交方式
1)自动提交,这是MySQL数据库的默认提交事务的方式,即输入完SQL语句后,回车自动提交事务。
2)手动提交,通过修改将默认提交方式改为手动提交,把SQL语句输入完之后,执行commit;才将其提交,否则一直不提交。
注意事项
1)MySQL 中只有使用了 Innodb 和bdb存储引擎的数据库或表才支持事务。
2)对于少量的数据更新,建议不使用事务,直接输入SQL语句更加快捷。
3)事务中的SQL语句要么全部执行,要么全部不执行,写入时尽量避免语句错误。
事务控制语句
事务控制语句是使用事务的基础,务必牢记。
BEGIN或START TRANSACTION:开启一个事务。
ROLLBACK或ROLLBACK WORK:手动回滚,结束用户的事务,还原到创建事务之前的状态。
SAVEPOINT EnglishNUM:在事务中创建保存点,可以通过回滚恢复到保存点的位置。
COMMIT或COMMIT WORK:提交事务,并将数据库进行的所有操作永久修改。
RELEASE SAVEPOINT EnglishNUM:删除一个事务的保存点。
ROLLBACK TO EnglishNUM:把事务回滚到指定保存点位置。
事务实际应用
创建一个表,并在其中插入一些数据,用于测试。
mysql> create table test(id int auto_increment primary key,name varchar(6) not null,age tinyint unsigned not null);
mysql> insert into test values(1,'张三',23),(2,'李四',24),(3,'王五',25);
查看表中记录
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 1 | 张三 | 23 |
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
事务操作案例
接下来就开始测试了
创建事务:begin或start transaction
提交事务:commit
mysql> begin;
开启事务后,在其中进行的操作在没有提交之前,是不会对数据库的实际数据进行修改的,在事务中的查看是将你操作后的效果显示出来罢了。对于谨慎操作时,还是比较有效果的。
mysql> delete from test where id=1; 删除id为1的记录
mysql> select * from test; 在事务中查看test表记录
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
在事务中查看,id为1的记录是已经消失了,但新建一个终端,登录到数据库中查看,发现id为1的记录依然存在。
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 1 | 张三 | 23 |
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
回到创建了事务的终端,将事务提交后,发现操作才会实际执行,也就是删除id为1的记录。
mysql> commit;
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
回滚操作案例
在使用回滚(rollback)的时候需要注意,回滚只在事务中才会生效,若事务已经提交,则对数据的修改是永久的,无法通过回滚还原。
回滚:rollback
查看test表记录
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
创建一个事务,并对数据进行修改
mysql> begin;
mysql> update test set name='张三' where id=2;
mysql> update test set name='赵六' where id=3;
将姓名修改后,查看test表记录
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 张三 | 24 |
| 3 | 赵六 | 25 |
+----+--------+-----+
想要将一切都还原,只需要将回滚一下就可以了。
mysql> rollback;
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
这样一切都还原到创建事务之前的状态了,没有对数据进行任何操作,也可以将事务提交,并且不会出现报错。
mysql> commit;
回滚点操作案例
对于回滚操作,还是有些死板的,毕竟直接回滚会将事务中所有的SQL语句删除,而创建回滚点(Rollback point)就不一样了,将任务输入一半时,可以创建一个回滚点,那么后续的SQL语句出错,回滚到保存的回滚点,就可以少输入一半的SQL语句,但要注意,虽说回滚点可以存在多个,但只能回滚1次。
创建回滚点:savepoint 英文字母数字
转到回滚点:rollback to 英文字母数字
还是先查看test表记录
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
先创建一个回滚点
mysql> savepoint a1;
接着对记录进行修改操作
mysql> update test set name='哈哈哈' where id=2;
mysql> update test set name='嘿嘿嘿' where id=3;
创建第二个回滚点
mysql> savepoint a2;
删除一条记录
mysql> delete from test where id=3;
查看修改后的test表记录
mysql> select * from test;
+----+-----------+-----+
| id | name | age |
+----+-----------+-----+
| 2 | 哈哈哈 | 24 |
+----+-----------+-----+
接下来就可以通过回滚点进行回滚。
在回滚的时候需要注意,可以按照倒序的方式进行回滚,也就是有1,2两个回滚点,先回滚2,再回滚1。
而另一种方式是按照顺序进行回滚,先回滚1,但是2就无法进行回滚了,回滚到1后,其中保存的只是回滚点1中的之前的数据,并没有回滚点2中的数据。简单点来说,就是游戏的存档,你打完第一关存档,打完第二关也存档,当你回到第一关存档中后,你还需要从新过第二关是一个道理。
转到回滚点2中
mysql> rollback to a2;
mysql> select * from test;
+----+-----------+-----+
| id | name | age |
+----+-----------+-----+
| 2 | 哈哈哈 | 24 |
| 3 | 嘿嘿嘿 | 25 |
+----+-----------+-----+
转到会滚点1中
mysql> rollback to a1;
mysql> select * from test;
+----+--------+-----+
| id | name | age |
+----+--------+-----+
| 2 | 李四 | 24 |
| 3 | 王五 | 25 |
+----+--------+-----+
删除回滚点
最后将创建的回滚点删除
mysql> release savepoint a1;