博客
关于我
09- 数据库事务
阅读量:86 次
发布时间:2019-02-25

本文共 2497 字,大约阅读时间需要 8 分钟。

10.1 什么是事务

事务是一个整体,由一条或多条SQL语句组成,这些SQL语句要么都执行成功,要么都执行失败。只要有一条SQL出现异常,整个操作就会回滚,整个业务执行失败。

例如:银行的转账业务,Kobe给Curry转账500元,至少要操作两次数据库,Kobe-500,Curry+500。这中间任何一步出现问题,整个操作必须全部回滚,这样才能保证用户和银行都没有损失。


10.2 模拟转账操作

(1) 创建账户表

CREATE TABLE account (    id INT PRIMARY KEY AUTO_INCREMENT,    NAME VARCHAR(10),    money DOUBLE);SELECT * FROM account;INSERT INTO account(NAME, money) VALUES('kobe', 1000), ('curry', 1000);

(2) 模拟Kobe给Curry转500元钱,一个转账的业务操作最少要执行下面语句

-- 给Kobe-500UPDATE account SET money = money - 500 WHERE name = 'kobe';-- 给Curry+500UPDATE account SET money = money + 500 WHERE name = 'curry';

10.3 事务回滚

事务回滚是指在事务运行过程中发生某种故障,事务不能继续执行,系统将事务中对数据库的所有已完成的操作全部撤销,滚回到事务开始时的状态(在提交之前执行)。


10.4 MySQL事务操作

在MySQL中,可以有两种方式进行事务的操作:手动提交事务和自动提交事务。

10.4.1 手动提交事务

功能 语句
开启事务 START TRANSACTION
提交事务 COMMIT
回滚事务 ROLLBACK

10.4.2 手动提交事务流程

  • 成功提交事务流程:

  • 开启事务
  • 执行多条SQL语句
  • 提交事务
  • 失败提交事务流程:

  • 开启事务
  • 执行多条SQL语句
  • 事务回滚

10.4.3 成功案例

(1) 命令行登录数据库

(2) 使用数据库

USE db_mysql;

(3) 开启事务

START TRANSACTION;

(4) 执行转账操作

-- 给Kobe-500UPDATE account SET money = money - 500 WHERE name = 'kobe';-- 给Curry+500UPDATE account SET money = money + 500 WHERE name = 'curry';

(5) 提交事务

COMMIT;

(6) 查看结果


10.4.4 自动提交事务

MySQL默认每一条DML(增删改)语句都是一个单独的事务,每条语句都会自动开启一个事务,语句执行完毕后自动提交事务。


10.4.5 取消自动提交

MySQL默认是自动提交事务,可以设置为手动提交。

(1) 查看autocommit状态

SHOW VARIABLES LIKE 'autocommit';

(2) 设置手动提交

SET @@autocommit=off;

10.5 事务的四大特性 ACID

特性 含义
原子性 每个事务都是一个整体,所有SQL语句要么都成功,要么都失败。
一致性 事务执行前后数据库状态保持一致。
隔离性 事务与事务之间保持隔离,不互相影响。
持久性 事务执行成功后,数据库修改持久有效。

10.6 事务隔离级别


10.6.1 数据并发访问

一个数据库可能拥有多个访问客户端,这些客户端都可以并发方式访问数据库。数据库的相同数据可能被多个事务同时访问,如果不采取隔离措施,会导致各种问题,破坏数据的完整性。


10.6.2 并发访问产生的问题

问题 含义
脏读 一个事务读取到了另一个事务中尚未提交的数据。
不可重复读 一个事务中两次读取的数据内容不一致。
幻读 一个事务中某一次的SELECT操作得到的数据状态无法支撑后续业务操作。

10.6.3 四种隔离级别

级别 常见操作 脏读 不可重复读 幻读 数据库默认隔离级别
1 读未提交
2 读已提交 Oracle、SQLServer
3 可重复读 MySQL
4 串行化(可串行化)

10.6.4 隔离级别相关命令

(1) 查看隔离级别

SELECT @@tx_isolation;

(2) 设置事务隔离级别

SET global transaction isolation level {read uncommitted, read committed, repeatable read, serializable};

10.7 隔离性问题


10.7.1 脏读演示

脏读是指一个事务读取到了另一个事务中尚未提交的数据。

10.7.2 解决脏读问题

将全局隔离级别设置为read committed

SET global transaction isolation level read committed;

10.7.3 不可重复读演示

不可重复读是指一个事务中两次读取的数据内容不一致。


10.7.4 解决不可重复读问题

将全局隔离级别设置为repeatable read

SET global transaction isolation level repeatable read;

10.7.5 幻读演示

幻读是指一个事务中某一次的SELECT操作得到的数据状态无法支撑后续业务操作。


10.7.6 解决幻读问题

将事务隔离级别设置为serializable

SET global transaction isolation level serializable;

通过合理设置隔离级别,可以有效防止并发访问引起的脏读、不可重复读和幻读问题。不过,serializable隔离级别会导致事务只能排队执行,严重影响数据库性能,数据库通常不会使用这种隔离级别。

转载地址:http://rcp.baihongyu.com/

你可能感兴趣的文章
MySQL中UPDATE语句的神奇技巧,让你操作数据库如虎添翼!
查看>>
Mysql中varchar类型数字排序不对踩坑记录
查看>>
MySQL中一条SQL语句到底是如何执行的呢?
查看>>
MySQL中你必须知道的10件事,1.5万字!
查看>>
MySQL中使用IN()查询到底走不走索引?
查看>>
Mysql中使用存储过程插入decimal和时间数据递增的模拟数据
查看>>
MySql中关于geometry类型的数据_空的时候如何插入处理_需用null_空字符串插入会报错_Cannot get geometry object from dat---MySql工作笔记003
查看>>
mysql中出现Incorrect DECIMAL value: '0' for column '' at row -1错误解决方案
查看>>
mysql中出现Unit mysql.service could not be found 的解决方法
查看>>
mysql中出现update-alternatives: 错误: 候选项路径 /etc/mysql/mysql.cnf 不存在 dpkg: 处理软件包 mysql-server-8.0的解决方法(全)
查看>>
Mysql中各类锁的机制图文详细解析(全)
查看>>
MySQL中地理位置数据扩展geometry的使用心得
查看>>
Mysql中存储引擎简介、修改、查询、选择
查看>>
Mysql中存储过程、存储函数、自定义函数、变量、流程控制语句、光标/游标、定义条件和处理程序的使用示例
查看>>
mysql中实现rownum,对结果进行排序
查看>>
mysql中对于数据库的基本操作
查看>>
Mysql中常用函数的使用示例
查看>>
MySql中怎样使用case-when实现判断查询结果返回
查看>>
Mysql中怎样使用update更新某列的数据减去指定值
查看>>
Mysql中怎样设置指定ip远程访问连接
查看>>