Back End

TCL语言

PineappleCat · 2月2日 · 2021年 200次已读

概念

一、含义
事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行
二、特点(ACID)

  • A 原子性:一个事务是不可再分割的整体,要么都执行要么都不执行
  • C 一致性:一个事务可以使数据从一个一致状态切换到另外一个一致的状态
  • I 隔离性:一个事务不受其他事务的干扰,多个事务互相隔离的
  • D 持久性:一个事务一旦提交了,则永久的持久化到本地

事务的特性

步骤案例

三、事务的使用步骤 ★
了解:
    * 隐式(自动)事务:没有明显的开启和结束,本身就是一条事务可以自动提交,比如insert、update、delete
    * 显式事务:具有明显的开启和结束前提:必须先设置自动提交功能为禁用

使用显式事务:
①开启事务
set autocommit=0; 或 start transaction;
②编写一组逻辑sql语句
注意:sql语句支持的是insert、update、delete
设置回滚点:savepoint 回滚点名;
③结束事务
提交:commit;
回滚:rollback;
回滚到指定的地方:rollback to 回滚点名;

#1.演示事务的使用步骤
DROP TABLE IF EXISTS account;
CREATE TABLE account(
	id INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAR(20),
	balance DOUBLE
);
INSERT INTO account(username,balance)
VALUES('张无忌',1000),('赵敏',1000);
#开启事务
SET autocommit=0; 或 START TRANSACTION;
#编写一组事务的语句
UPDATE account SET balance = 1000 WHERE username='张无忌';
UPDATE account SET balance = 1000 WHERE username='赵敏';
#结束事务
rollback;
commit;
SELECT * FROM account;
#实现转账功能
#开启事务
#start transaction; 每次提交或回滚之后都要再次执行一次,才开启事务。
#禁用自动提交 ,每次提交或回滚之后都会自动开启事务。
set autocommit=0;
#1 转出账户扣钱
	update account set money=money-1000 where id=1;
#出现异常、断电
#2 转入账户加钱
	update account set money=money+1000 where id=2;
#提交
commit;
#回滚
rollback;
select * from account;

四种隔离级别

#1 演示脏读
# 灿灿同学 
# 查询隔离级别 
select @@tx_isolation; #默认隔离级别 REPEATABLE-READ

#转账
start transaction;
update account set money=money-1000 where id=1;
update account set money=money+1000 where id=2;
commit;
rollback;
select * from account;

#龙哥
#修改当前连接的隔离级别
#set session transaction isolation level read UNCOMMITTED
set session transaction isolation level read COMMITTED
select * from account;
#2 演示不可重读
#银行统计 :  统计三次一样才可以
start TRANSACTION;
#原先10000
SELECT sum(money) from account;
#执行到这又加1000 = 21000
SELECT sum(money) from account;
#21000
SELECT sum(money) from account;
commit;	

三次读取的钱数不一样:要求不可重复读。
怎么办?设置隔离级别为不可重读。事务一开起统计的三次都一样,在读取的时候再进行添加操作,等下次开启事务的时候读取,不会丢失。
#3 演示幻读(虚读)  在事务执行过程中,如果有另外一个事务添加一条数据,当前事务读取到了
银行第一次读取到100000,这个时候又有人开户存了1000,这个事务中可能会读取新家进来的账户余额,
造成三次读取不一样。MySQL已经解决了这个问题,不会读取到。
  • 可重复读的读和写是不互斥的
  • SERIALIZABLE读写互斥
四、并发事务
1、事务的并发问题是如何发生的?
多个事务 同时 操作 同一个数据库的相同数据时
2、并发问题都有哪些?
	对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题:
	脏读:一个事务读取了其他事务还没有提交的数据,读到的是其他事务“更新”的数据
	不可重复读:一个事务多次读取,结果不一样
	幻读:一个事务读取了其他事务还没有提交的数据,只是读到的是 其他事务“插入”的数据
3、如何解决并发问题
数据库事务的隔离性: 数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题.
一个事务与其他事务隔离的程度称为隔离级别. 数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发性越弱
	通过设置隔离级别来解决并发问题
4、隔离级别
			 脏读	   不可重复读	     幻读
read uncommitted:读未提交     ×                ×              ×        
read committed:读已提交      √                ×              ×
repeatable read:可重复读     √                √              ×
serializable:串行化          √                √              √
Oracle 支持的2 种事务隔离级别:READ COMMITED, SERIALIZABLE。
Oracle 默认的事务隔离级别为: READ COMMITED
Mysql 支持4 种事务隔离级别. Mysql 默认的事务隔离级别为: REPEATABLE READ

查看隔离级别
select @@tx_isolation;
设置隔离级别
set session|global transaction isolation level 隔离级别;

回滚点的演示 savepoint 节点名;设置保存点
SET autocommit=0;

START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a;#设置保存点
DELETE FROM account WHERE id=28;
ROLLBACK TO a;#回滚到保存点
SELECT * FROM account;


Click here to view the copyright notice of this site(点击此处查看本站版权声明)
0 条回应

必须 注册 为本站用户, 登录 后才可以发表评论!