MySQL事务

事务处理

事务处理机制在应用程序开发过程中有着非常重要的作用,它可以保证在同一个事务中的操作具有同步性,从而让整个应用程序更安全。本节将针对事务处理进行详细讲解。

事务概述

在现实生活中,人们经常会进行转账操作,转账可分为转入和转出两部分,只有这两个部分都完成才认为转账成功。在数据库中,转账过程中的SQL语句只要任意一条语句出现异常没有执行成功,就会导致两个账户的转账金额不同步,出现转账错误。MySQL中可以使用事务避免上述情况的发生。

在MySQL中,事务就是针对数据库的一组操作,它可以由一条或多条SQL语句组成。在程序执行过程中,只要有一条SQL语句执行失败或发生错误,其他语句都不会执行;也就是说,事务中的语句要么都执行,要么什么都不执行。

1.原子性

原子性是指一个事务必须被视为一个不可分割的最小工作单元,只有事务中所有的数据库操作都执行成功,才算整个事务执行成功。事务中如果有任何一个5OL语句决行失败,已经执行成功的SQL语句也必须撤销,数据库的状态退回到执行事务前的状态。

2.一致性

一致性是指事务将数据库从一个一致状态转变为下一个一致状态。在事务完成之前和完成之后,都要保证数据库内的数据处于一致状态。

3.隔离性

隔离性是指当一个事务在执行时,不会受到其他事务的影响。隔离性保证了未完成事务的所有操作与数据库系统的隔离,直到事务完成之后,才能看到事务的执行结果。当多个用户并发访问数据库时,数据库为每一个用户开启的事务不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

4.持久性

持久性是指事务一旦提交,对数据库中数据的修改就是永久性的。需要注意的是,事务的持久性不能做到百分之百的持久,只能从事务本身的角度来保证永久性,如果一些外部原因导致数据库发生故障(如硬盘损坏),那么所有提交的数据可能都会丢失。

事务的基本操作

在MySQL中,每一条SQL语句都会被默认为是一条单独的事务自动提交。如果想要将一组SQL语句作为一个事务,需要在执行这组SQL语句之前开启事务。开启事务的语法格式如下:

START TRANSACTION;

执行上述语句之后,后续的每一条SQL语句将不再自动进行提交,需要我们进行手动提交。只有事务提交之后,事务中的SQL语句才会执行。手动提交事务的语句如下:

COMMIT;

如果不想提交当前的事务,还可以取消事务(也就是回滚事务),具体语句如下:

ROLLBACK;

回滚事务只能回滚未提交的事务,不能回滚已经提交的事务。

例如,我们现在想要在部门表里面增加一个部门,但是为了以防万一,我们先开启事务:

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

事务开启后我们再往dept里面添加一条数据:

mysql> INSERT INTO dept VALUES(40,'运营部');
Query OK, 1 row affected (0.01 sec)

数据添加好之后我们使用SELECT语句查看一下:

mysql> select * from dept;
+--------+-----------+
| deptno | dname     |
+--------+-----------+
|     10 | 总裁办    |
|     20 | 研究院    |
|     40 | 运营部    |
|     30 | 销售部    |
+--------+-----------+
4 rows in set (0.00 sec)

数据添加好之后发现部门添加错了,那么我们需要对事务进行回滚:

mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)

回滚之后我们再来查看一下数据表:

mysql> SELECT * FROM dept;
+--------+-----------+
| deptno | dname     |
+--------+-----------+
|     10 | 总裁办    |
|     20 | 研究院    |
|     30 | 销售部    |
+--------+-----------+
3 rows in set (0.00 sec)

从结果显示运营部并没有在数据表中,说明我们的事务起了作用。这个时候公司说明了要创建一个主管部门,而且这个消息很准确,那么我们也就有自信保证过程不会出错,创建好之后直接提交事务:

mysql> INSERT INTO dept VALUES(40,'主管部');
Query OK, 1 row affected (0.00 sec)

mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)

数据创建好之后我们再来查看一下数据:

mysql> SELECT * FROM dept;
+--------+-----------+
| deptno | dname     |
+--------+-----------+
|     40 | 主管部    |
|     10 | 总裁办    |
|     20 | 研究院    |
|     30 | 销售部    |
+--------+-----------+
4 rows in set (0.00 sec)

从结果我们可以看到主管部门成功的添加到了数据表中。至此事务已经结束。、

需要注意的是MySQL中的事务不允许嵌套,也就是说上一个事务没结束,我们就又再创建一个事务,此时的第二个事务开启时的语句START TRANSACTION语句会隐式执行上一个事务的提交操作。此操作不可逆。

事务的保存点

在回滚事务时,事务内的所有操作都会被撤销。如果只希望撤销部分操作,则可以借助事务的保存点实现。事务中创建保存点的语法格式如下:

SAVEPOINT 保存点名;

在事务中设置好保存点后,可以将事务回滚到指定的保存点。事务中的设置保存点的语法格式如下:

ROLLBACK TO SAVEPOINT 保存点名;

如果某个保存点不再使用,可以使用下面的语法进行删除:

RELEASE SAVEPOINT 保存点名;

一个事务中可以创建多个保存点。一旦提交事务,事务中所有的保存点都会被删除,如果事务回到某个保存点后,该保存点之后创建的其他保存点也会被删除。

例如,由于公司发展过快,公司规模也是不断的扩大,现在又要创建新的部门,先对当先公司部门信息进行查看;

mysql> SELECT * FROM dept;
+--------+-----------+
| deptno | dname     |
+--------+-----------+
|     40 | 主管部    |
|     10 | 总裁办    |
|     20 | 研究院    |
|     30 | 销售部    |
+--------+-----------+
4 rows in set (0.00 sec)

经过公司总裁办的决定,现在公司要创建一个运营部,具体SQL语句及执行结果如下:

mysql> START TRANSACTION;  开启事务
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO dept VALUES(50,'运营部');
Query OK, 1 row affected (0.00 sec)

为了保险起见,再查看一下数据表的信息:

mysql> SELECT * FROM dept;
+--------+-----------+
| deptno | dname     |
+--------+-----------+
|     40 | 主管部    |
|     10 | 总裁办    |
|     20 | 研究院    |
|     50 | 运营部    |
|     30 | 销售部    |
+--------+-----------+
5 rows in set (0.00 sec)

然后创建保存点:

mysql> SAVEPOINT s1;
Query OK, 0 rows affected (0.00 sec)

过了一会公司又决定要把运营部的名字改为技术部:

mysql> UPDATE dept SET dname='技术部' WHERE deptno=50;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

事后公司发现有些不妥,要求技术人员改回运营部,具体SQL语句及执行结果如下:

mysql> ROLLBACK TO SAVEPOINT s1;
Query OK, 0 rows affected (0.00 sec)

这时我们就用到了保存点,使用保存点能直接返会到我们第一次创建数据的时候。

保存点讲完了,数据也该回滚了:

mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)

关于MySQL事务这篇文章就讲了一部分,如果大家感兴趣的话可以去官网拓展拓展。

  • 32
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值