博客
关于我
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/

你可能感兴趣的文章
mysqli
查看>>
MySQLIntegrityConstraintViolationException异常处理
查看>>
mysqlreport分析工具详解
查看>>
MySQLSyntaxErrorException: Unknown error 1146和SQLSyntaxErrorException: Unknown error 1146
查看>>
Mysql_Postgresql中_geometry数据操作_st_astext_GeomFromEWKT函数_在java中转换geometry的16进制数据---PostgreSQL工作笔记007
查看>>
mysql_real_connect 参数注意
查看>>
mysql_secure_installation初始化数据库报Access denied
查看>>
MySQL_西安11月销售昨日未上架的产品_20161212
查看>>
Mysql——深入浅出InnoDB底层原理
查看>>
MySQL“被动”性能优化汇总
查看>>
MySQL、HBase 和 Elasticsearch:特点与区别详解
查看>>
MySQL、Redis高频面试题汇总
查看>>
MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
查看>>
mysql一个字段为空时使用另一个字段排序
查看>>
MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
查看>>
MYSQL一直显示正在启动
查看>>
MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
查看>>
MySQL万字总结!超详细!
查看>>
Mysql下载以及安装(新手入门,超详细)
查看>>
MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
查看>>