MYSQL——访问控制、事务处理与并发控制(3)

177 阅读6分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第23天,点击查看活动详情

MYSQL——访问控制、事务处理与并发控制(3)

需要:

       了解组角色、角色、用户的概念及他们之间的区别;

       了解数据库的不同权限;

       掌握为用户分配权限及收回权限的方法;

       掌握数据库事务管理的基本原理,包括显式事务、事务提交、事务回滚、隐式事务等,以及事务的编程方法。

       掌握数据库并发控制的基本原理及其应用方法。

显式事务、事务提交、事务回滚、隐式事务等的编程方法:

1、准备测试数据

在 banks 数据库中创建数据表 account,用于完成转账功能:

CREATE DATABASE banks CHARSET=utf8;
USE banks;
CREATE TABLE  account (
   id  INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
   username  VARCHAR(32) NOT NULL UNIQUE COMMENT '账户名',
   money  DECIMAL(10,2) NOT NULL COMMENT '存款金额'
)ENGINE=INNODB CHARSET=utf8;

       需要注意的是,在 MySQL 数据库中,要想对数据表进行事务处理,需要将其存储引擎设置为 InnoDB。

2、开启事务

在MySQL数据库中,使用事务之前必须先开启事务,具体SQL语句如下。

START TRANSACTION;
# 或
BEGIN;

       执行上述语句后,若MySQL中没有返回警告或错误信息提示,则初始化事务成功,可以继续执行以下的操作了

3、创建事务

       创建事务就是在事务开启后,执行的一系列 SQL 语句。例如,开启事务处理后,向表 account 中插入两条测试数据,具体如下。

START TRANSACTION;
INSERT INTO  account  VALUES (NULL, '张三', 5000), (NULL, '李四', 100);

       上述SQL语句执行后,通过SELECT查询执行结果。

SELECT * FROM account;

4、提交事务

       在用户没有提交事务前,其他连接MySQL服务器的用户进程是看不到当前事务的处理结果的。

       新创建一个mysql连接“连接2”,进入到banks数据库中查看数据表account中的数据。

USE banks;
SELECT * FROM account;

       在原来的连接客户端,对上述创建的事务进行提交操作,具体SQL语句如下。

COMMIT;

       执行上述语句后,在“连接2”客户端再次执行SELECT查询。

5、撤销事务

       撤销事务也称事务回滚,用于创建事务时执行的SQL语句与业务逻辑不符或操作错误时,通过ROLLBACK命令撤销对数据库的所有操作,或利用ROLLBACK TO SAVEPOINT回滚到指定位置。撤销事务的操作在实际应用中,有着非常重要的作用。

① 撤销全部事务处理

       假设张三转让李四一辆二手自行车,李四需要向张三支付199元,则执行的SQL语句如下。

       在第一个连接窗口执行如下语句:

START TRANSACTION;
UPDATE  account  SET  money = money +199 WHERE username='张三';
UPDATE  account  SET  money = money -199 WHERE username='李四';

       上述SQL语句执行后,通过SELECT查询执行结果。

SELECT * FROM account;

       从查询结果可知,李四的账户余额为负数,显然不符合正常的业务逻辑。此时就需要使用ROLLBACK命令进行全部事务的回滚,撤销刚才对数据表account的更新操作。具体SQL语句如下。

ROLLBACK;

       执行完事务回滚后再进行SELECT查询,结果与开始创建事务查询结果相同。

SELECT * FROM account;

② 撤销事务到指定位置

       使用SAVEPOINT可以在事务处理使用指定不同的撤销位置,在需要事务撤销时进行回滚。例如,向数据表account中逐条插入3条记录,并利用SAVEPOINT在每次插入数据后设置一个回滚位置,SQL语句如下。

START TRANSACTION;
INSERT INTO account VALUES (NULL, '王五', 500);
SAVEPOINT test1;
INSERT INTO account VALUES (NULL, '赵六', 6000);
SAVEPOINT test2;
INSERT INTO account VALUES (NULL, '李七', 70);
SAVEPOINT test3;
SELECT * FROM account;

       上述SQL执行后,进行SELECT查询,就会看到account表中已经存在新插入的这3条记录。

       假设从“李七”开始的记录有误需要撤销,就可以回滚到test2位置,具体SQL如下。

ROLLBACK TO SAVEPOINT test2;

       执行上述SQL语句后,查询数据表account中的数据,就会看到新插入的记录中只有“王五”和“赵六”。由此可见,事务可以回滚到想要的位置。

       需要注意的是,SAVEPOINT指定回滚位置的操作对于已经提交的事务并不适用,且对于定义了相同名称的回滚位置,则后面的定义会覆盖之前的定义。此外,对于不再需要使用的回滚位置标识,可以通过RELEASE SAVEPOINT命令进行删除。例如,删除回滚位置test1,SQL语句如下。

RELEASE SAVEPOINT test1;

       CHAIN和RELEASE子句可以用来分别定义在事务提交或者回滚之后的操作,CHAIN会立即启动一个新事物,并且和刚才的事务具有相同的隔离级别;RELEASE则会断开和客户端的连接。

6、事务的自动提交

       MySQL中默认操作就是自动提交模式。除非显示地开启一个事务(START TRANSACTION),否则所有的SQL都会被当做单独的事务自动提交(COMMIT)。因此,如果用户想要控制事务的自动提交方式,可以通过AUTOCOMMIT来实现,具体如下。

SET AUTOCOMMIT=0;

       通过上述语句即可关闭MySQL中的自动提交功能,实现了只有用户手动执行提交(COMMIT)操作,MySQL才会将事务提交到数据库系统中。否则,若不执行手动提交,而终止MySQL会话,数据库会自动执行回滚操作。

       在第一个连接窗口执行如此下语句:

SET AUTOCOMMIT=0;
INSERT INTO `account` VALUES (NULL, '王丽', 45);
SELECT * FROM account;

       到第2各窗口查看数据,发现语句并未提交。

       执行如下语句,回复MySQL的默认自动提交模式

SET AUTOCOMMIT=1;