SQL中的事务

目录

1、概述
---1.1事务是什么?
---1.2例子:银行转账业务
---1.3四个特征ACID
---1.4和事务有关的两条SQL语句(TCL)
---1.5事务开启和结束的标志

2、事务的提交和回滚的演示
---2.1事务的提交
---2.2事务的回滚
---2.3手动设置事务开关

3、事务的隔离级别
---3.1read uncommitted 读未提交(级别最低)
---3.2read committed 读已提交
---3.3repeatable read 可重复读
---3.4serializable 串行化(序列化)
---3.5查看隔离级别
---3.6设置隔离级别
---3.7隔离级别不一致性问题的关系

概述

事务是什么?

1、一个最小的不可再分的工作单元;
2、通常一个事务对应一个完整的业务;(如:银行转账业务)
3、而一个完整的业务需要批量的DML(insert、update、delete)语句共同完成;
4、事务只和DML语句有关系,或者说只有DML语句才有事务(保证数据的安全性);
5、以上所描述的批量DML语句共有多少DML语句,这个和业逻辑有关系,业务逻辑不同DML语句个数不同 。
6、一些关键词:
1、开启事务:start transaction
2、结束事务:end transaction
3、提交事务:commit transaction
4、回滚事务:rollback transaction

例子:银行转账业务

1、银行转账业务:是一个完整的业务,最小的单元,不可再分。
2、act-001(50000.0)转10000.0给act-002(10000.0),操作如下:

update t_act set balance = 40000.0 
where actno = ‘act-001’;
update t_act set balance = 20000.0 
where actno = ‘act-002’;

3、分析
a)以上两条DML语句必须同时成功或者同时失败,因为它为最小业务单元,不可拆分;
b)当第一条DML语句执行成功之后,并不能将底层数据库中的第一个账户的数据修改,只是将操作记录了一下,这个记录是在内存中完成的;
c)当第二条DML语句执行成功之后,和底层数据库文件中的数据完成同步。
d)若第二条DML语句执行失败,将清空所有的历史操作记录。
结论:要完成以上功能,必须借助事务(transaction)。

四个特征ACID

1、原子性(Atomicity)
事务是最小单元,不可再分;
2、一致性(Consistency)
事务要求所有的DML语句操作的时候,必须保证同时成功或同时失败;
3、隔离性(Isolation)
一个事务不会影响其它事务的运行;
4、持久性(Durability)
在事务完成之后,该事务对数据库所作的更改将持久地保存在数据库中,并不会被回滚。

和事务有关的两条SQL语句(TCL)

1、COMMIT; 提交
2、ROLLBACK; 回滚

事务开启和结束的标志
  • 开启的标志
    任何一条DML语句执行,标志事务的开启。
  • 结束的标志
    提交(commit)或者回滚(rollback)
    1、提交:成功的结束,将所有的DML语句操作记录和底层硬盘文件中数据进行一次同步。
    2、回滚:失败的结束,将所有DML语句操作记录全部清空。
  • 重点
    1、在事务进行过程中,未结束之前,DML语句是不会修改底层数据库文件中的数据。
    2、只是将历史操作记录一下,在内存中完成记录。
    3、只有在事务成功结束的时候才会修改底层硬盘文件中的数据。

事务的提交和回滚的演示

  • 自动提交事务
    在MySQL数据库管理系统中,默认情况下,事务是自动提交的。也就是说,叧要执行一条DML语句,就开启了事务,并且提交了事务。
事务的提交
  • 第一步:start transaction; 手动开启事务;
    SQL中的事务
  • 第二步:DML语句…. 执行批量DML语句;
INSERT INTO t_user(`name`) 
VALUES(‘lisi‘);
INSERT INTO t_user(`name`) 
VALUES(‘zhaoliu‘);
SELECT * FROM t_user;

当前窗口可以查看刚刚插入的数据:
SQL中的事务
其它窗口则看不见:
SQL中的事务

  • 第三步:commit; 手动提交事务(事务成功结束)。
    SQL中的事务
    提交后都能看见:
    SQL中的事务
事务的回滚
  • 第一步:start transaction;手动开启事务
    SQL中的事务
  • 第二步:DML语句…..批量DML语句
INSERT INTO t_user(`name`) 
VALUES(‘jack‘);
INSERT INTO t_user(`name`) 
VALUES(‘rose‘);
SELECT * FROM t_user;

当前窗口:
SQL中的事务
其它窗口:
SQL中的事务

  • 第三步:rollback;手动回滚事务(事务失败结束)
    SQL中的事务
    其它窗口:
    SQL中的事务
手动设置事务开关

1、两种关闭自动提交事务
a)set autocommit = off;
b)set session autocommit = off;

set autocommit = off;
show variables like ‘%commit%‘;

SQL中的事务
2、两种打开自动提交事务
a)set autocommit = on;
b)set session autocommit = on;

set autocommit = on;
show variables like ‘%commit%‘;

SQL中的事务
注意:以上打开或关闭事务只对当前窗口有效。
3、查询事务状态:show variables like ‘%commit%‘;
SQL中的事务

事务的隔离级别

事务四个特性ACID之一:隔离性(isolation)

  • 隔离性有四个隔离级别:
    1、read uncommitted 读未提交
    2、read committed 读已提交
    3、repeatable read 可重复读
    4、serializable 串行化
read uncommitted 读未提交(级别最低)

1、事务A和和事务B,事务A未提交的数据,事务B可以读取;
2、这里读取到的数据可以叫做“脏数据”或“脏读 Dirty Read”;
3、读未提交隔离级别最低,这种级别一般叧在理论上存在,数据库默认隔离级别一般都高于该隔离级别。

read committed 读已提交

1、事务A和事务B,事务A提交的数据,事务B才可读取到;
2、该隔离级别高于“读未提交”级别;
3、换句话说:对方事务提交之后的数据,当前事务才可读取到;
4、该隔离级别可以避免脏数据;
5、该隔离级别能够导致“不可重复读取”(只能读到对方事务提交之后的数据(更新后的),不能读到原来的数据);
6、Oracle数据库管理系统默认隔离级别为:读已提交。

repeatable read 可重复读

1、事务A和事务B,事务A提交之后的数据,事务B读取不到;
2、事务B是可重复读到数据的;
3、这种隔离级别高于“读已提交”;
4、换句话说,对方提交之后的数据,还是读取不到;
5、这种隔离级别可以避免“脏读和不可重复读”,达到“重复读取”;
6、MySQL数据库管理系统默认隔离级别为:可重复读;
7、虽然可以达到“可重复读”效果,但是会导致“幻象读”(只能读到原来的数据)。

serializable 串行化(序列化)

1、事务A和事务B,事务A在操作数据库表中数据的时候,事务B只能排队等待(解决了以上所有问题,但是效率太低);
2、这种事务隔离级别一般很少使用,吞吐量太低,用户体验不好;
3、这种隔离级别可以避免“幻象读”,每一次读取都是数据库表中真实的记录;
4、事务A和事务B不再并发。

查看隔离级别
  • 查看当前会话级隔离级别
    select @@session.transaction_isolation;
    SQL中的事务
  • 查看当前全局隔离级别:
    select @@global.transaction_isolation;
    SQL中的事务
设置隔离级别
  • 事务隔离级别的作用范围分为两种:会话级、全局级
    1、会话级(session):只对当前会话有效。
    2、全局级(global):对所有会话有效。
  • 例子
    SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED 事务隔离级别
    事务隔离级别:
    --- READ UNCOMMITTED
    --- READ COMMITTED
    --- REPEATABLE READ
    --- SERIALIZABLE
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED
select @@global.transaction_isolation;

SQL中的事务

隔离级别不一致性问题的关系
隔离级别 脏读 不可重复读 幻象读
读未提交
读已提交 ×
可重复读 × ×
串行化 × × ×

SQL中的事务

上一篇:百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:


下一篇:C#对图片文件的压缩、裁剪操作初探