华子目录
- 什么是事务
- 银行转账案例
- 方式1
- 方式2
- 具体操作
- 事务的四大特性
- 并发事务问题
- 脏读
- 不可重复读
- 幻读
- 事务的隔离级别
- 查看事务隔离级别
- 设置事务隔离级别
- session与global的区别
什么是事务
- 事务(transaction),一个最小的不可再分的工作单元,通常一个事务对应一个完整的业务。例如银行账户转账业务,该业务就是一个最小的工作单元。一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成
- 要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成
银行转账案例
- 以银行转账为例:账户转账是一个完整的业务,最小的单元,不可再分——也就是说银行账户转账是一个事务
方式1
MySQL默认已经开启自动提交,我们可以通过对应的设置来开启或者关闭自动提交。(默认MySQL的事务是自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务)
#查看事务提交方式
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
#设置事务提交方式
mysql> set @@autocommit=0; #0为不自动提交(手动提交)
Query OK, 0 rows affected (0.00 sec)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
#提交事务
mysql> commit;
#完成一个事务,一旦事务提交成功 ,就说明具备ACID特性了。
#回滚事务
mysql> rollback;
#将内存中,已执行过的操作,回滚回去
方式2
说明:在5.5 以上的版本,不需要手工begin,只要你执行的是一个DML,会自动在前面加一个begin命令。
#开启事务
mysql> begin;
或
mysql> start transaction;
#提交事务
mysql> commit;
#完成一个事务,一旦事务提交成功 ,就说明具备ACID特性了。
#回滚事务
mysql> rollback;
具体操作
- 张三给李四转1000元
mysql> select* from account;
+----+--------+-------+
| id | name | money |
+----+--------+-------+
| 1 | 张三 | 2000 |
| 2 | 李四 | 2000 |
+----+--------+-------+
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update account set money=money-1000 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update account set money=money+1000 where id=2;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from account;
+----+--------+-------+
| id | name | money |
+----+--------+-------+
| 1 | 张三 | 1000 |
| 2 | 李四 | 3000 |
+----+--------+-------+
2 rows in set (0.00 sec)
mysql> rollback; #回滚
Query OK, 0 rows affected (0.00 sec)
mysql> select * from account;
+----+--------+-------+
| id | name | money |
+----+--------+-------+
| 1 | 张三 | 2000 |
| 2 | 李四 | 2000 |
+----+--------+-------+
2 rows in set (0.00 sec)
事务的四大特性
事务是由一组SQL语句 组成的逻辑处理单元,它的ACID特性如下:
- 原子性(Atomicity): 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
- 一致性(Consistency): 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
- 隔离性(Isolation): 事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
- 持久性(Durability): 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
并发事务问题
脏读
指一个事务读取了另外一个事务未提交的数据。
- 事务A在完成第二步后还没有commit,事务B就select了数据库,事务B就拿到了事务A update的数据
不可重复读
一个事务先后读取同一条记录,但两次读取的数据不同
- 事务A在第二次select数据库前,事务B就已经update并commit了事务。
幻读
一个事务按条件插询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了“幻影”。
- 事务A在第一次select数据库时发现没有数据,在第二次insert前,事务B已经insert并commit了数据,当事务A在insert数据时,发现insert失败(说明已经存在数据),这时事务Aselect时,发现这行数据存在。
事务的隔离级别
为了解决并发事务问题,SQL标准定义了以下几种事务隔离级别
- Read uncommitted:最低级别,以上情况均无法保证。(读未提交)
- Read committed:可避免脏读情况发生(读已提交)。
- Repeatable read:可避免脏读、不可重复读情况的发生。(可重复读)
- Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化)
查看事务隔离级别
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ |
+-------------------------+
设置事务隔离级别
mysql> set [session/global] transaction isolation level [read uncommitted/read committed/repeatable read/serializable]
注:事务隔离级别越高,数据越安全,但是性能越低
session与global的区别
在MySQL中,SESSION
和GLOBAL
关键字用于设置系统变量的作用域。系统变量是用来配置MySQL服务器的。
-
SESSION
关键字用于设置当前会话的系统变量值。这意味着这个变量的值只会影响到当前与MySQL服务器连接的客户端会话。当这个会话结束时,变量的值会被丢弃,并恢复为默认值或服务器启动时设置的值。在一个会话中设置的变量值不会影响到其他会话。 -
GLOBAL
关键字用于设置服务器全局系统变量的值。这个变量的值会影响到所有新建立的会话。已经存在的会话不会受到影响,除非它们在GLOBAL
变量改变之后被重新设置了SESSION
变量的值。只有具有足够权限的用户才能设置GLOBAL
变量,因为这会影响到服务器上所有用户的操作。
例如,如果你想要更改服务器的SQL模式只对当前会话有效,你可以这样做:
SET SESSION sql_mode = 'STRICT_TRANS_TABLES';
如果你想要更改服务器的SQL模式并让它对所有会话有效,你可以使用:
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES';