1.事务-基本演示
1.1.概述
如果一个包含了多个步骤的业务操作被事务管理,那么这些操作要么同时成功,要么同时失败.
1.2.事务的操作
-
-
开启事务 -> START TRANSACTION
-
回滚 -> ROLLBACK
-
提交 -> COMMIT
-
1.3.手动提交事务使用过程:
1) 执行成功的情况: 开启事务 ——>执行多条 SQL 语句——> 成功提交事务
2) 执行失败的情况: 开启事务——>执行多条 SQL 语句——> 事务的回滚
1.4.事务使用
-- 创建账户表
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(100),
balance DOUBLE
);`changgou_config`
-- 添加两条记录`account`
INSERT INTO account (`name`,balance) VALUE ('zhagsan',1000),('lisi',1000);
-- 张三转账500给李四
UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
-- 查询
SELECT * FROM account;
-- 开启事务
-- 张三转账500给李四
-- 1.开启事务
START TRANSACTION ;
-- 2.张三给李四转500
UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
-- 遇到错误
出现错误了。。。。。。。。。。
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
-- 成功:提交事务
COMMIT;
失败:
回滚事务:
-- 失败:回滚事务 ROLLBACK
1.5.事务原理
事务开启之后, 所有的操作都会临时保存到事务日志中, 事务日志只有在得到 commit 命令才会同步到数据表中,其他任何情况都会清空事务日志(rollback,断开连接) 。
原理图:
事务的步骤:
1) 客户端连接数据库服务器,创建连接时创建此用户临时日志文件
2) 开启事务以后,所有的操作都会先写入到临时日志文件中
3) 所有的查询操作从表中查询,但会经过日志文件加工后才返回
4) 如果事务提交则将日志文件中的数据写到表中,否则清空日志文件。
2.事务-默认自动提交&手动提交
-
事务提交的两种方式
-
手动提交
-
需要事先开启事务再进行提交.
-
-
自动提交
-
MYSQL默认就是自动提交,一条DML语句会自动提交一次事务.
-
-
-
查看当前MYSQL的事务提交方式
-- 查看事务的默认提交方式 SELECT @@AUTOCOMMIT; -- 结果为1代表自动提交,结果为0代表手动提交.
-
修改MYSQL的事务提交方式
-- 修改事务的默认提交方式 SET @@AUTOCOMMIT = 0;
默认提交方式修改为手动后,执行DML操作需要执行COMMIT语句
修改事务提交方式只针对当前访问客户端有效
3.事务-事务四大特征束
-
事务的四大特征:
-
原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
-
持久性:当事务提交或回滚后,数据库会持久化的保存数据。
-
隔离性:多个事务之间,相互独立。
-
一致性:事务操作前后,数据总量不变
-
4.事务-事务隔离级别介绍
-
概念:
-
多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
-
-
事务的隔离级别存在的问题
-
MYSQL中的隔离级别
什么是串行化? 其实Java序列化和Java串行化都是一样的,都对应英文中的Serializable。 一个对象随着创建而存在,随着程序结束而结束。那如果我要保存一个对象的状态呢?Java序列化能够将对象的状态写入byte流存储起来,也从其他地方将byte流读取出来,重新构造一个新的对象。这种机制允许你将对象通过网络进行传播,并且可以随时把对象持久化到数据库、文件系统中。简而言之,序列化就是将一个对象的状态保存起来,而反序列化就是将已经保存的流对象恢复成原来的对象。
-
查询当前MYSQL的隔离级别
-- 查看MYSQL的默认隔离级别 SELECT @@tx_isolation;
-
设置当前MYSQL的隔离级别
-- 设置当前MYSQL的隔离级别 SET GLOBAL TRANSACTION ISOLATION LEVEL 级别字符串;
5._事务-事务隔离级别演示1
-
操作语句
-
设置事务的隔离级别为: READ UNCOMMITTED
-
不同的客户端产生:脏读,不可重复读
-
脏读示例代码
SELECT @@tx_isolation; -- 设置当前MYSQL的隔离级别为 READ UNCOMMITTED SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; START TRANSACTION; UPDATE account SET balance = balance - 500 WHERE id = 1; UPDATE account SET balance = balance + 500 WHERE id = 2; ROLLBACK;
回滚前,在其他客户端可以查到修改未提交数据。
-
设置事务的隔离级别为: READ COMMITTED
-
不同的客户端:解决了脏读问题,不能解决不可重复读
SELECT @@tx_isolation; -- 设置当前MYSQL的隔离级别为 READ COMMITTED SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; START TRANSACTION; UPDATE account SET balance = balance - 500 WHERE id = 1; UPDATE account SET balance = balance + 500 WHERE id = 2; ROLLBACK;
其他客户端同一事务,两次查询不一致。
-
6._事务-事务隔离级别演示2
-
设置事务的隔离级别为: REPEATABLE READ
-
不同的客户端:解决了脏读问题,解决了不可重复读,不能解决幻读
-
示例代码
SELECT @@tx_isolation; -- 设置当前MYSQL的隔离级别为 REPEATABLE READ SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ; START TRANSACTION; UPDATE account SET balance = balance - 500 WHERE id = 1; UPDATE account SET balance = balance + 500 WHERE id = 2; ROLLBACK;
同一个事务,两次查询一致
-
MVCC解决了幻读