目录

一、事务简介

 二、事务操作

三、事务四大特性(ACID)

四、并发事务问题

1.  脏读

 2.  不可重复读

 3.  幻读

 五、事务隔离级别


一、事务简介

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

举例说明:最典型例子:银行转账(张三向李四转一千块钱)

  1. 正常情况:

查询张三账户余额

mysql事务如何实现 mysql事务_数据库

张三账户余额 -1000

mysql事务如何实现 mysql事务_mysql_02

李四账户余额 +1000

mysql事务如何实现 mysql事务_mysql_03

  1. 异常情况: (此时张三减少的钱不能加给李四)

mysql事务如何实现 mysql事务_事务隔离级别_04

mysql事务如何实现 mysql事务_mysql_05

因此,我们想要解决这种异常,我们就需要通过 数据库的事务 来解决,将上述三个操作定义在一个事务当中,要么全部执行成功,要么全部执行失败。

  1. 解决情况:(事务)

mysql事务如何实现 mysql事务_数据库_06

mysql事务如何实现 mysql事务_mysql_07

回滚事务就是指将之前临时修改的数据恢复回去,即初始化。

 对于MySQL数据库来说,事务是默认自动提交的,也就是说当我们进行增删改的某一条语句时,语句结束完,事务就提交给数据库,数据库中数据就会立刻变更过来。

 二、事务操作

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

SELECT @@autocommit ;(自动提交)

          SET @@autoconnit = 0;(手动提交)

  • 提交事务:START TRANSACTION 或 BEGIN;
  • 提交事务:COMMIT;
  • 回滚事务:ROLLBACK;

上述例子操作:

-- 创建表添加数据
create table account(
    id int auto_increment primary key comment '主键',
    name varchar(10) comment '姓名',
    money int comment '金额'
)comment '账户表';
insert into account (id, name, money) values (null,'张三',2000),(null,'李四',2000);

update account set money = 2000 where name = '张三' or  name = '李四';

-- 方式一:
select @@autocommit;

set @@autocommit = 0;

-- 转账操作
-- 1.查询张三账户余额
select * from account where name = '张三';
-- 2.张三账户余额 -1000
update account set money = money - 1000 where  name = '张三';
程序抛出异常...
-- 3.李四账户余额 +1000
update account set money = money + 1000 where  name = '李四';

-- 提交事务
commit ;
-- 回滚事务
rollback ;



-- 方式二:
-- 转账操作

-- 开启事务
start transaction ;

-- 1.查询张三账户余额
select * from account where name = '张三';
-- 2.张三账户余额 -1000
update account set money = money - 1000 where  name = '张三';
程序抛出异常...
-- 3.李四账户余额 +1000
update account set money = money + 1000 where  name = '李四';

-- 提交事务
commit ;
-- 回滚事务
rollback ;

三、事务四大特性(ACID)

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

四、并发事务问题

并发事务问题指 事务A 和 事务B 在同时操作某一个数据库甚至是某一张表时,所引发的一些问题。

问题

描述

脏读

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

不可重复读

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

幻读

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

1.  脏读

事务A第一步操作执行完后执行第二步操作,但是事务没有执行完毕是没有提交的,事务A第二步操作结束完后会对数据库表中数据进行更新,此时另外一步事务B进行查询操作,而事务B查询到的正好是事务A第二步操作更新的数据,但是事务A并没有提交。

mysql事务如何实现 mysql事务_mysql_08

 2.  不可重复读

事务A执行第一步操作后,开始执行第二步操作同时事务B执行更新操作,操作结束后将数据提交到数据库,接着事务A执行第三步操作,此时第一步操作和第三部操作都为一样的查询语句,但是结果不同。

mysql事务如何实现 mysql事务_数据_09

 3.  幻读

事务A执行第一步操作,此时事务B也执行操作,执行完毕将数据提交给数据库,接着事务A执行第二步操作,但是发现执行失败,对应主键已经存在,但是当执行第三步操作时,执行结果为空。

mysql事务如何实现 mysql事务_mysql事务如何实现_10

 五、事务隔离级别

根据上述我们对并发事务问题的了解,接下来我们就学习事务隔离级别来解决这些问题:

隔离级别

脏读

不可重复读

幻读

Read uncommitted




Read committed




Repeatable Read(默认)




Serializable




  • 查看事务隔离级别:SELECT @@TRANSACTION_ISOLATION;
  • 设置事务隔离级别:SET [ SESSION | GLOBAL ] TRANSACTION ISOLATON LEVEL { READUNCOMMITTED | READ COMMITED│REFPEATABLE READ│ SERALZABLE

注意:事务隔离级别越高,数据越安全,但是性能越低。