MySQL数据库——事务

本文深入探讨了MySQL中的事务,包括事务的理解、实例、基本操作、在银行转账中的应用及注意事项。详细阐述了事务的隔离级别,如脏读、不可重复读和幻读的问题及其解决方案,并介绍了事务的ACID特性。通过对事务的全面了解,有助于更好地管理和维护数据库的一致性。
摘要由CSDN通过智能技术生成

(一)对事务的理解

  • 事务是一组DML(数据操纵语言).
  • 它们在逻辑上存在相关性,这一组语句是一个整体,要么全部成功,要么全部失败。
  • 事务规定不同的客户端看到的数据是不相同的。

(二)使用事务的实例理解

例如银行转账中,
张三存入了100块钱,李四存入了200块钱;
现在张三要给李四转50块钱;
正常情况下转账结束以后张三还有50块钱,李四有250块钱。

首先,先用一条语句更新张三的账户信息,从张三的账户中减50块钱。
接下来使用一条语句更新李四的账户信息,在李四的账户中加50块钱。

但是由于操作人员的失误,给李四的账户中加了 55 块钱,即给李四的账户多加了5块钱。
此时一种方法是再使用一条语句在李四的账户中减去五块钱,但是此方法风险性太高,不建议使用。
另外一种方法就是返回到给张三账户减去50语句成功之后,怎样回到上一个状态呢,这时就可以使用事务。使用事务的话可以不断设置保存点,当之后的语句出现错误时,可以直接回到任意保存点,也可以选择回到初始状态。
在这里插入图片描述

(三)事务的基本操作

  1. start transaction——开始事务
  2. savapoint 保存点名——设置保存点
  3. rollback to 保存点名——返回保存点
  4. rollback——返回初始状态
  5. commit——提交事务

(四)对银行转账实例的应用

把转账的过程看成一次事务。
银行转账过程如下:

  1. 创建一个银行账户表
  2. 向表中添加纪录
  3. 进行银行转账——开启事务
    3.1 更新张三的账户数据(减去50)
    3.2 设置保存点zs
    3.3 更新李四的账户数据(出错,加了55)
    3.4 回滚至保存点zs
    3.5 重新更新李四的账户数据
  4. 提交事务
//1. 创建一个银行账户表
mysql> create table account(
    -> id int unsigned auto_increment primary key,
    -> name varchar(20),
    -> balance int
    -> );
Query OK, 0 rows affected (0.04 sec)
//2. 向表中添加纪录
mysql> insert into account(name,balance) values 
    ->('张三','100'),
    ->('李四','200');
//查看表中信息 
mysql> select * from account;
+----+------+---------+
| id | name | balance |
+----+------+---------+
|  1 | 张三 |     100 |
|  2 | 李四 |     200 |
+----+------+---------+
//3. 进行银行转账——开启事务
start transaction;
 //3.1 更新张三的账户数据(减去50)
 update account set balance=balance-50 where id=1;
 //查看此时表中信息
 mysql> select * from account;
+----+------+---------+
| id | name | balance |
+----+------+---------+
|  1 | 张三 |      50 |
|  2 | 李四 |     200 |
+----+------+---------+
 //3.2 设置保存点zs
 savepoint zs;
 //3.3 更新李四的账户数据(出错,加了55)
 update account set balance=balance+55 where id=2;
 //查看此时表中信息
 mysql> select * from account;
+----+------+---------+
| id | name | balance |
+----+------+---------+
|  1 | 张三 |      50 |
|  2 | 李四 |     255 |
+----+------+---------+ 
 //3.4 回滚至保存点zs
 rollback to zs;
 //查看此时表中信息
 mysql> select * from account;
+----+------+---------+
| id | name | balance |
+----+------+---------+
|  1 | 张三 |      50 |
|  2 | 李四 |     200 |
+----+------+---------+
 //3.5 重新更新李四的账户数据
 update account set balance=balance+50 where id=2;
 //查看表中数据信息
 mysql> select * from account;
+----+------+---------+
| id | name | balance |
+----+------+---------+
|  1 | 张三 |      50 |
|  2 | 李四 |     250 |
+----+------+---------+
 //4. 提交事务
 commit

(五)使用事务的注意事项

  1. 如果没有设置保存点,也可以回滚,只能回滚到事务的初始状态(直接使用rollback);
  2. 如果一个事务已经被提交了,则不可以回滚。
  3. 可以在事务中设置多个保存点,选择回退到哪个保存点。
  4. 开始事务使用start transaction;
  5. InnoDB引擎支持事务,MyISAM引擎不支持事务。

(六)事务的隔离级别

不隔离容易产生的三个问题:

  1. 脏读
    (1)一个事务读取了另一个事务修改但未提交的数据。
    即一个事务对数据进行了修改,但是还没有提交,此时另一个事务读取了这个数据,这时读到的数据即为脏读。
    (2)解决办法:在一个事务修改数据但未提交的时候不允许其他事务读取该数据。
  2. 不可重复读
    (1) 在一个事务中,读取了一条数据,此时,又有一个新的事务访问了该数据并且修改了数据,则原来的事务再次读取这条数据的话读到的结果是不一样的(即不能读到相同的数据),称为不可重复读。
    (2)解决方法:只有在修改事务提交之后才可以读取数据。
  3. 幻读
    (1)如第一个事务对表中所有数据进行修改,此时另一个事务向表中重新插入一个记录,则第一个事务再次读取数据的时候发现表中还有未修改的数据,好像发生了幻觉一样。
    (2)解决方法:在操作事务完成处理之前,其他事务不可以添加事务。


    事务的隔离级别
隔离级别脏读不可重复读幻读加锁读
读未提交(read uncommited)不加锁
读已提交(read commited)不加锁
可重复读(repeated read)不加锁
可串行化(serializable)加锁

注:

  1. ✔会发生该问题,✘不会发生该问题。
  2. mysql默认为可重复读
  3. 加锁:同一时间只能有一个事务访问数据表。

(1)设置事务的隔离级别

注意:修改的只是当前事务的隔离级别。

set session transaction isolation level 隔离级别;

(2)查看当前的隔离级别

select @@tx_isolation;

(七)事务的ACID特性

  1. 原子性(Atomicity)
    事务是应用中最小的执行单位,如原子一样不可再分,事务是应用中不可再分的最小逻辑执行体。
  2. 隔离型(IsolationConsistency)
    各个事务的执行互不干扰,任意一个事务的内部操作对其他并发事务都是隔离的。即并发执行的事务不能看到对方的中间状态,不能互相影响。
  3. 一致性(Consistency)
    数据执行的结果,必须使数据库从一个一致性状态变到另一个一致性状态。
  4. 持久性(Durability)
    事务一旦被提交,它对数据库所做的改变都要记录到永久存储中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值