目录
一、什么是事务
二、事务的属性(面试重点)
事务的属性也就是事务的特点,经常会出现面试中。
(1)原子性(Atomicity):一个事务中的所有 SQL 语句构成最小单元,要么全部执行成功,要么全部执行失败,不会结束在中间的某个环节。
(2)一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。简单说就是操作前后它的总量是不变的。
(3)隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。简单的说就是多个事务是相互独立的不会产生影响。
(4)持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。简单的说就是当提交事务后,表中的数据不会再发生变化。
三、事务执行流程
与事务控制有关的 SQL 命令包括:
(1)BEGIN 或者 START TRANSACTION:开始事务;
(2)COMMIT:提交事务;
(3)ROLLBACK:回滚事务;
(4)SAVEPOINT:在事务内部设置回滚标记点;
(5)RELEASE SAVEPOINT:删除回滚标记点;
(6)ROLLBACK TO:将事务回滚到标记点(ROLLBACK 命令的一种变形写法)。
事务控制命令仅能与 DML 类别的 SQL 命令一起使用,包括 INSERT、UPDATE、DELETE 和SELECT,在创建或者删除表时不能使用事务,因为这些操作在数据库中是自动提交的。
3.1、开启事务
开始事务有以下两种命令,选择其一即可:
begin;
或者:
start transaction;
3.2、提交事务
提交事务使用如下命令:
commit;
CREATE TABLE customers (
id int primary key auto_increment,
name varchar(20),
age int(2),
address varchar(20),
salary float(6,2)
);
INSERT INTO customers (NAME, AGE, ADDRESS, SALARY)
VALUES ('Ramesh', 32, 'Ahmedabad', 2000.00 );
INSERT INTO customers (NAME, AGE, ADDRESS, SALARY)
VALUES ('Khilan', 25, 'Delhi', 1500.00 );
INSERT INTO customers (NAME, AGE, ADDRESS, SALARY)
VALUES ('kaushik', 23, 'Kota', 2000.00 );
执行后:
打开一个 MySQL 命令行窗口(我们称它为 A 窗口),使用事务向表中插入两条数据:
begin ;
INSERT INTO customers (NAME, AGE, ADDRESS, SALARY)
VALUES ('Chaitali', 25, 'Mumbai', 6500.00 );
INSERT INTO customers (NAME, AGE, ADDRESS, SALARY)
VALUES ('Hardik', 27, 'Bhopal', 8500.00 );
select * from customers;
说明在 console 窗口中插入的数据还未成功。
commit;
select * from customers;
3.3、回滚事务
rollback;
BEGIN;
DELETE FROM customers WHERE ID=4;
DELETE FROM customers WHERE ID=5;
SELECT * FROM customers;
发现console窗口中数据已被删除。
SELECT * FROM customers;
rollback;
执行完上面的命令后,就撤销了那两条删除语句。
此时console中的数据又回来了。
3.4、回滚标记
SAVEPOINT point_name;
BEGIN;
DELETE FROM customers WHERE ID=4;
savepoint mydelete; -- 添加回滚标记
DELETE FROM customers WHERE ID=5;
rollback to mydelete; -- 回滚到标记
select * from customers;
四、事务隔离级别(面试重点)
4.1、什么是事务隔离级别
4.2、查看隔离级别
select @@transaction_isolation;
查看版本:
select VERSION();
4.3、设置隔离级别
set [作用域] transaction isolation level [事务隔离级别];
SET [SESSION | GLOBAL]
TRANSACTION ISOLATION LEVEL
{READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
set global transaction isolation level read committed;
设置后需要重启窗口才能看到。
4.4、演示隔离级别
CREATE TABLE `tb_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
`age` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
INSERT INTO `tb_user`(name,age) VALUES('瀚海', 18);
4.4.1、读未提交
set global transaction isolation level read uncommitted;
select @@transaction_isolation;
注意:执行完上面语句后,需要重新开启新的会话窗口才能看到设置的隔离级别,在本窗口是没有效果的。
begin ;
select * from tb_user;
然后我们在 console_7 窗口中执行如下:
begin ;
update tb_user set age=20 where id=1;
select * from tb_user;
然后我们在 console_7 窗口中执行如下:
rollback;
select * from tb_user;
此时,当我们把 console_7 事务回滚后,会发现我们查询的数据就不一致。这就是一个事务读取到了另一个未提交的更新事务。
4.4.2、读已提交
set global transaction isolation level read committed;
select @@transaction_isolation;
use mydb;
begin;
select * from tb_user;
我们在 console_8 中执行如下:
use mydb;
begin;
update tb_user set age=5 where id=1;
commit;
此时的查询结果就是提交事务后的执行结果。
4.4.3、可重复读
set global transaction isolation level repeatable read;
启动两个事务,分别为事务 console_8 和事务 console_10。
begin;
select * from tb_user;
use mydb;
begin;
update tb_user set age=1 where id=1;