mysql事务学习
作者:互联网
事务
mysql中,事务能保证业务的完整性
,是用户定义的一个数据操作序列,这些操作要么全做,要么全不做
,是一个不可分割的工作单位。
例:银行转账:
A 转100元 给B
A账户 -100
B账户 +100
出现错误,没有一起成功,100元将无故丢失。
mysql控制事务
在 MySQL 中,事务的自动提交状态默认是开启的。
系统变量:autocommit
(
用于控制是否自动提交事务)
- autocommit = 1 :每条语句自动提交,立即生效。
- autocommit = 0 :每条语句必须使用
commit
提交事务生效,使用rollback
撤销事务。
//查看变量autocommit --默认自动提交
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
//修改变量 --关闭自动提交
mysql> set autocommit=0;
Query OK, 0 rows affected (0.01 sec)
将自动提交关闭后,测试数据回滚:
INSERT INTO user VALUES (2, 'b', 1000);
-- 关闭 AUTOCOMMIT 后,数据的变化是在一张虚拟的临时数据表中展示,
-- 发生变化的数据并没有真正插入到数据表中。
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
| 1 | a | 1000 |
| 2 | b | 1000 |
+----+------+-------+
-- 数据表中的真实数据其实还是:
+----+------+-------+
| id | name | money |
+----+------+-------+
| 1 | a | 1000 |
+----+------+-------+
-- 由于数据还没有真正提交,可以使用回滚
ROLLBACK;
-- 再次查询
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
| 1 | a | 1000 |
+----+------+-------+
将虚拟的数据真正提交到数据库中
INSERT INTO user VALUES (2, 'b', 1000);
-- 手动提交数据(持久性),
-- 将数据真正提交到数据库中,执行后不能再回滚提交过的数据。
COMMIT;
-- 提交后测试回滚
ROLLBACK;
-- 再次查询(回滚无效了)
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
| 1 | a | 1000 |
| 2 | b | 1000 |
+----+------+-------+
手动开启一个事务
基本操作 | 说明 |
---|---|
start transaction; / begin; | (手动)开始事务 |
commit; | 结束事务,提交()全部完成 |
rollback | 结束事务,回滚(回到初始状态) |
autocommit = 1自动提交事务状态下,不改变系统变量,手动开启一个事务
BEGIN;
UPDATE user set money = money - 100 WHERE name = 'a';
UPDATE user set money = money + 100 WHERE name = 'b';
-- 由于手动开启的事务没有开启自动提交,
-- 此时发生变化的数据仍然是被保存在一张临时表中。
SELECT * FROM user;
+----+------+-------+
| id | name | money |
+----+------+-------+
| 1 | a | 900 |
| 2 | b | 1100 |
+----+------+-------+
-- 提交数据
COMMIT;
-- 测试回滚(无效,因为表的数据已经被提交)
ROLLBACK;
事务的四大特性(ACID)
- 原子性::事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
- 一致性:一致性代表了底层数据存储的完整性。数据库中只包含成功事务提交的结果;若其中包含失败的结果,则其他成功也为失败状态。
- 隔离性:隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
- 持续性:事务一旦结束 ( COMMIT ) ,就不可以再返回了 ( ROLLBACK ) 。持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失。
数据库并发可能会出现的问题
- 脏读(读未提交):
事务A读取到了事务B执行,但是并没有提交(commit)的事务,并且最终事务B开启了回滚(rollback)回到了最初状态
。 - 不可重复读(读已提交):
事务A读取数据表中数据,进行操作,同时,事务B也操作这张表,并且对数据表进行了数据修改并提交,然后事务A操作表,发现结果与读取到的表信息前后不一致
。 - 幻读:
事务A和事务B同时操作一张表,事务A提交的数据,不能被事务B读到
,这就是幻读。举例:(系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后关闭事务发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。)
事务的隔离性可分为四种 ( 性能从低到高 ) :
-
READ UNCOMMITTED ( 读取未提交 )
如果有多个事务,那么任意事务都可以看见其他事务的未提交数据。
-
READ COMMITTED ( 读取已提交 )
只能读取到其他事务已经提交的数据。
-
REPEATABLE READ ( 可被重复读 )
如果有多个连接都开启了事务,那么事务之间不能共享数据记录,否则只能共享已提交的记录。
-
SERIALIZABLE ( 串行化 )
所有的事务都会按照固定顺序执行,执行完一个事务后再继续执行下一个事务的写入操作。(这意味着队列中同时只能执行一个事务的写入操作 )
查看当前数据库的默认隔离级别:
-- MySQL 8.x, GLOBAL 表示系统级别,不加表示会话级别。
SELECT @@GLOBAL.TRANSACTION_ISOLATION;
SELECT @@TRANSACTION_ISOLATION;
+--------------------------------+
| @@GLOBAL.TRANSACTION_ISOLATION |
+--------------------------------+
| REPEATABLE-READ | -- MySQL的默认隔离级别,可以重复读。
+--------------------------------+
-- MySQL 5.x
SELECT @@GLOBAL.TX_ISOLATION;
SELECT @@TX_ISOLATION;
修改隔离级别:
-- 设置系统隔离级别,LEVEL 后面表示要设置的隔离级别 (READ UNCOMMITTED)。
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-- 查询系统隔离级别,发现已经被修改。
SELECT @@GLOBAL.TRANSACTION_ISOLATION;
+--------------------------------+
| @@GLOBAL.TRANSACTION_ISOLATION |
+--------------------------------+
| READ-UNCOMMITTED |
+--------------------------------+
标签:事务,--,money,学习,提交,mysql,+----+------+-------+,SELECT 来源: https://blog.csdn.net/qq_49067108/article/details/110682911