数据库
首页 > 数据库> > MySQL事务

MySQL事务

作者:互联网

何为事务? 一言蔽之,事务是逻辑上的一组操作,要么都执行,要么都不执行。

事务演示

经典的转账问题

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> update account set money = money-1000 where name = 'sora';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> update account set money = money+1000 where name = 'shiro';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from account;
+----+-------+-------+
| id | name  | money |
+----+-------+-------+
|  1 | sora  |  4000 |
|  2 | shiro |  6000 |
+----+-------+-------+
2 rows in set (0.00 sec)

关系型数据库(例如:MySQLSQL ServerOracle 等)事务都有 ACID 特性:

  1. 原子性Atomicity) : 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  2. 一致性Consistency): 执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
  3. 隔离性Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
  4. 持久性Durabilily): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

并发事务带来了哪些问题?

在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对同一数据进行操作)。并发虽然是必须的,但可能会导致以下的问题。

不可重复读和幻读有什么区别呢?

幻读其实可以看作是不可重复读的一种特殊情况,单独把区分幻读的原因主要是解决幻读和不可重复读的方案不一样。

问题演示

1.脏读

//先将隔离级别设置为read uncommitted
mysql> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> update account set money = money+1000 where name='sora';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

//这就是脏读,还没有提交事务,这个数据是错误的
mysql> select * from account where name = 'sora';
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | sora |  4000 |
+----+------+-------+
1 row in set (0.00 sec)

2.不可重复读

mysql> set session transaction isolation level read committed;
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
//第一次的数据
mysql> select * from account where name = 'sora';
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | sora |  5000 |
+----+------+-------+
1 row in set (0.00 sec)
//另一个事务提交以后
mysql> select * from account where name ='sora';
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | sora |  6000 |
+----+------+-------+
1 row in set (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> update account set money = money+1000 where name = 'sora';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

3.幻读

幻读好像有点问题,提交了好像就能查询到。

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into account values(3,'kaze',5000);
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.01 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from account where id = 3;
Empty set (0.00 sec)

mysql> select * from account where id = 3;
Empty set (0.00 sec)

mysql> insert into account values(3,'kaze',5000);
ERROR 1062 (23000): Duplicate entry '3' for key 'PRIMARY'
mysql> select * from account where id = 3;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  3 | kaze |  5000 |
+----+------+-------+
1 row in set (0.00 sec)

MySQL 的默认隔离级别是什么?

MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。我们可以通过SELECT @@tx_isolation;命令来查看,MySQL 8.0 该命令改为SELECT @@transaction_isolation;

mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+

SQL 标准定义了哪些事务隔离级别?

SQL 标准定义了四个隔离级别:


隔离级别 脏读 不可重复读 幻读
READ-UNCOMMITTED
READ-COMMITTED ×
REPEATABLE-READ × ×
SERIALIZABLE × × ×

标签:事务,affected,0.00,MySQL,sec,mysql,OK
来源: https://www.cnblogs.com/xiaoovo/p/16589169.html