MySQL 事务主要用于处理操作量大,复杂度高的数据。简单说,用户A向用户B转账1000块钱,首先A的账户余额要减掉1000元,对应的用户B的账户需要增加1000元,类似的操作即可构成为一个事务。如果第一次操作用户A的余额成功减掉了1000元,但是银行的系统此时突然断电瘫痪导致用户B的账户金额增加失败,如果没有处理机制,那么将会是非常严重的事情
- 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
- 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
- 事务用来管理 insert,update,delete 语句
一般来说,事务是必须满足4个条件(ACID):即原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
-
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。例如用户B的账户金额增加失败,则将原款退还至用户A
-
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
-
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
-
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。
举例说明:
1、创建两个表,一个用户基本信息表,一个用户账户金额信息表
DROP TABLE IF EXISTS test.`users`;
CREATE TABLE test.`users` (
`id` BIGINT(64) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`account` VARCHAR(64) NOT NULL COMMENT '用户账号',
`password` VARCHAR(64) DEFAULT NULL COMMENT '用户密码',
`name` VARCHAR(64) DEFAULT NULL COMMENT '用户姓名',
`phone` VARCHAR(64) DEFAULT NULL COMMENT '用户手机号',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='用户基本信息表';
DROP TABLE IF EXISTS test.`account_amount`;
CREATE TABLE test.`account_amount` (
`id` BIGINT(64) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`userId` BIGINT(64) NOT NULL COMMENT '用户ID',
`money` DECIMAL(10,2) DEFAULT NULL COMMENT '用户账户金额',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='用户账户金额信息表';
2、执行insert语句
INSERT INTO test.`users`(account,PASSWORD,NAME,phone) VALUES('xiaowang','123','小王','123456');
INSERT INTO test.`users`(account,PASSWORD,NAME,phone) VALUES('xiaozhang','123','小张','456789');
INSERT INTO test.`users`(account,PASSWORD,NAME,phone) VALUES('xiaoli','123','小李','987654');
INSERT INTO test.`account_amount`(userId,money) VALUES('1','1000');
INSERT INTO test.`account_amount`(userId,money) VALUES('2','2000');
INSERT INTO test.`account_amount`(userId,money) VALUES('3','3000');
3、直接update用户小王的手机号
UPDATE test.`users` SET phone='666666' WHERE id=1;
执行之后查看数据库的数据,可发现数据已经修改成功
此时,我们查看数据库的事务默认的执行方式为自动提交事务。
SHOW VARIABLES LIKE 'autocommit';
那如果我们需要用事务来控制数据的更新怎么办呢?请接着往下看
事务控制语句:
-
BEGIN或START TRANSACTION;显式地开启一个事务;
-
COMMIT;也可以使用COMMIT WORK,不过二者是等价的。COMMIT会提交事务,并使已对数据库进行的所有修改成为永久性的;
-
ROLLBACK;有可以使用ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
-
SAVEPOINT identifier;SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT;
-
RELEASE SAVEPOINT identifier;删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;
-
ROLLBACK TO identifier;把事务回滚到标记点;
-
SET TRANSACTION;用来设置事务的隔离级别。InnoDB存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。
MYSQL 事务处理主要有两种方法:
1、用 BEGIN, ROLLBACK, COMMIT来实现
- BEGIN 开始一个事务
- ROLLBACK 事务回滚
- COMMIT 事务确认
2、直接用 SET 来改变 MySQL 的自动提交模式:
- SET AUTOCOMMIT=0 禁止自动提交
- SET AUTOCOMMIT=1 开启自动提交
举例说明:
1、开启一个事务,小王向小李转账500元,此时新打开一个窗口,作为一名新用户登陆查询所有用户的金额状况,如下图所示:
通过查看结果可知,所有的账户金额是没有发生变化的,也就是一个事务没有完成提交之前,作为新用户看到的是该事务提交前的最新数据
2、接下来继续操作,小李账户增加500元,commit提交事务,分别再次查询所有用户金额如下图所示
观察结果可知:所有用户查看到的结果均一致
3、事务回滚同理,例如小张账户增加1000元,系统故障。事务回滚ROLLBACK;
如果感觉博主写的可以,记得点赞哦!您的支持将是我坚持写作的不懈动力!
微信扫描下方二维码(新开通的个人微信公众号) 更多优质资源及优质文章及时获取 请大家多多支持哦