Mysql基础:05.TCL 事务控制语言

TCL:事务控制语言

TCL(Transaction Control Language)

一、事务

1. 事务的概念

一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行

2. 事务的特性(ACID)

  • 原子性(Atomicity):一个事务不可再分割,要么都执行要么都不执行
  • 一致性(Consistency):一个事务执行会使数据从一个一致状态切换到另外一个一致状态
  • 隔离性(Isolation):一个事务的执行不受其他事务的干扰
  • 持久性(Durability):一个事务一旦提交,则会永久的改变数据库的数据.

3. 事务的使用步骤

  • 隐式(自动)事务:没有明显的开启和结束,本身就是一条事务可以自动提交,比如insert、update、delete。autocommit为ON时则表示处于自动事务状态

    #在MySQL中查看autocommit状态
    SHOW VARIABLES LIKE 'autocommit';
    
  • 显式事务:事务具有明显的开启和结束的标记;前提:必须先设置自动提交功能为禁用(将autocommit设置为OFF)

3.1 事务的提交

事务语句一般只是基本的增删改查:select insert update delete,对于库表的操作,例如 alter drop等,不将其作为事务语句

#步骤1:开启事务
set autocommit=0;#设置自动提交功能为禁用
start transaction;#可选的

#步骤2:编写事务中的sql语句(select insert update delete)
语句1;
语句2;
...

#步骤3:结束事务,一般为提交事务或者回滚事务
commit;提交事务
#开启事务
SET autocommit=0;
START TRANSACTION;

#编写一组事务的语句
INSERT INTO major VALUES(1,'java');
INSERT INTO major VALUES(2,'c++');

#结束事务
commit;

值得注意的是更新和提交是两个概念。上面的sql语句中,执行commit语句之前,两条数据只是暂时放在内存中,只有当执行完commit语句后,磁盘中的数据库才发生更改。

那么如果结束事务的语句不是commit,而是rollback回滚,则这两条数据并不会存到磁盘中,即数据库不会发生改变

3.2 事务的回滚

3.2.1 基本操作

在结束事务时将commit改为rollback即可

#开启事务
SET autocommit=0;
START TRANSACTION;

#编写一组事务的语句
INSERT INTO major VALUES(1,'java');
INSERT INTO major VALUES(2,'c++');

#结束事务
commit;
#rollback;

3.2.2 保存点

保存点(回滚点)savepoint:保存事务状态的节点

#设置保存点
SAVEPOINT 保存点名;

#回滚到指定保存点
ROLLBACK TO 保存点名;

下面的事务结束后,id为2的不会删除,1会删除

SET autocommit=0;

DELETE FROM major WHERE id = 1;
SAVEPOINT a;#设置保存点a
DELETE FROM major WHERE id = 2;

ROLLBACK TO a;#回滚到保存点a

3.2.3 delete和truncate在回滚时候的区别

delete删除可以回滚,truncate删除不可以回滚

#delete删除
SET autocommit=0;
START TRANSACTION;
DELETE FROM major;#执行完不会删
ROLLBACK;

#truncate删除
SET autocommit=0;
START TRANSACTION;
TRUNCATE TABLE major;#执行完会删
ROLLBACK;

SELECT * FROM major;

二、并发事务

1. 并发事务的概念

多个事务同时操作同一个数据库相同数据时,称为并发事务,如果没有采取必要的隔离机制,容易出现事务的并发问题

2. 常见的并发问题

  • 脏读:一个事务读取了其他事务更新但没有提交的数据
  • 幻读:一个事务读取了其他事务插入或删除但没有提交的数据
  • 不可重复读:一个事务多次读取,结果不一样

3. 事务的隔离性与隔离级别

数据库事务的隔离性: 数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响。 因此需要设置隔离级别来解决并发问题

隔离级别:一个事务与其他事务隔离的程度称为隔离级别。 数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。下表为隔离级别与能否解决并发问题的对应关系

隔离级别 脏读 不可重复读 幻读
read uncommitted:读未提交(允许事务读取未被其它事务提交的变更) × × ×
read committed:读已提交(只允许事务读取已经被其它事务提交的变更,只能 避免脏读) × ×
repeatable read:可重复读(确保事务多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新,可以避免脏读和不可重复读) ×
serializable:串行化(确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有并发问题都可以避免,但性能低下)

Oracle 支持的2 种事务隔离级别:read committed(默认), serializable;MySQL支持4种隔离级别,默认为repeatable read

每启动一个MySQL程序,就会获得一个单独的数据库连接,每个连接都有一个全局变量@@transaction_isolation,表示当前的事务隔离级别

#查看当前MySQL连接的隔离级别
select @@transaction_isolation; # 旧版本可以用别名tx_isolation,新版本不可以

#设置当前MySQL连接的隔离级别
#set session transaction isolation level 隔离级别;
set session transaction isolation level read uncommitted;

#设置整个数据库系统全局的隔离级别,设置完需要重启
set global transaction isolation level 隔离级别;
上一篇:Vivado / Vitis HLS有什么奇技淫巧?


下一篇:[SCOI2009]迷路