MySQL学习笔记:6. 约束

目录

一、事务简介

二、事务操作

三、事务的四大特性(ACID)

四、并发事务的问题

五、事务的隔离级别


一、事务简介

事务:是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体,一起向系统提交或撤销操作请求,即这些操作要么同事成功,要么同时失败。

-- 案例:一个典型事务案例是银行转账
张三要给李四转账1000元,需要3个操作:
1、查询张三账户余额
2、张三账户余额-1000
3、李四账户余额+1000

以上三个操作必须全部成功,转账事务才成功。
假如在第3个操作出现了异常,而此时张三账户余额已经减少1000元了,而李四的余额却没有增加1000元!
这是不能容忍的,所以此时需要将3个操作置于事务范围当中。

1. 开启事务
2. 如果抛出异常,则回滚事务
3. 提交事务

事务回滚时,临时修改的数据,会被恢复。

注意:默认MySQL的事务是自动提交的,也就是说,当执行一条DML与对数据库进行增删改时,MySQL会立即隐式提交事务。
因此,我们要想把若干操作放在事务范围内时,需要手动开启事务、手动提交事务,如果出现异常,需要手动进行事务回滚。

二、事务操作

  • 查看/设置事务提交方式

SELECT @@autocommit;

SET @@autocommit=0;

(我尝试更改事务提交方式为手动,但是每次修改表数据,都会直接自动提交了,不知道为什么,先不管他,直接用开启事务的方式START TRANSACTION或BEGIN就不会有这个问题了)

  • 开启事务

START TRANSACTION 或 BEGIN;

  • 提交事务

COMMIT;

  • 回滚事务

ROLLBACK;

-- --------------------- 事务案例 ----------------------

-- 张三给李四进行转账操作

-- 数据准备
USE my_database;

DROP TABLE IF EXISTS account;

# 创建账户表
CREATE TABLE account(
    id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID',
    name VARCHAR(10) COMMENT '姓名',
    money INT DEFAULT 0 COMMENT '余额'
) COMMENT '账户表';

# 插入数据
INSERT INTO account (name, money) VALUES ('张三', 2000), ('李四', 2000);
SELECT * FROM account;

# 余额恢复
UPDATE account SET money = 2000 WHERE name = '张三' OR  name = '李四';
SELECT * FROM account;


-- 使用事务操作
# 查看事务提交方式
SELECT @@autocommit; # @@AUTOCOMMIT=1

# 设置事务提交方式为手动(只对当前QueryConsole生效)
SET @@autocommit=0;
SELECT @@autocommit;

# 转账操作:3个步骤
# 1、查询张三账户的余额
SELECT money FROM account WHERE name = '张三';

# 2、将张三账户的余额减1000
UPDATE account SET money = money - 1000 WHERE name = '张三';
# SELECT * FROM account;

# 3、将李四账户的余额加1000
# UPDATE account SET money = money + 1000 WHERE name = '李四';
# SELECT * FROM account;
# 假设在这里出现异常,李四的账户余额不会增加
UPDATE account SET money = money + 1000 WHERE name = '李X四';
# SELECT * FROM account;

# 提交事务
COMMIT;
SELECT * FROM account;

三、事务的四大特性(ACID)

  • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
  • 一致性(Consistency):事务完成时,必须使所有的数据都保持状态。
  • 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
  • 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据就是永久的。

四、并发事务的问题

第一次看这个并发事务问题,感觉和多线程同步问题很像。但是又很不理解,为什么数据还没提交就能被另一事务读取到。后面看完事务的隔离级别就明白了。

问题

描述

脏读

一个事务读到另一个事务还没有提交的数据。

不可重复读

一个事务先后读取同一条数据,但两次读取的数据不同,称之为不可重复读。

幻读

一个事务按照条件查询数据时,没有对应的数据航,但在插入数据时,又发现这行数据已经存在,好像出现了幻影。

五、事务的隔离级别

用于解决事务并发问题,事务的隔离级别有以下几种:

隔离级别

脏度

不可重复读

幻读

Read uncommitted

Read committed

×

Repeatable Read(默认)

×

×

Serializable

×

×

×

表格从上到下,事务隔离级别越来越高,数据安全性越来越高,同时并发处理性能越来越低。

在业务开发过程中,选择事务隔离级别时,既要考虑数据的安全性,又要权衡数据的并发性能。

如何查看和设置事务隔离级别?

  • 查看事务隔离级别

SELECT @@TRANSACTION_ISOLATION;

  • 设置事务隔离级别

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值