[MySQL]数据库中如何处理多事务

0.README


本文介绍了事务的基本概念,常用的四个命令,事务的四个特性,最后介绍多事务处理中的可能出现的三种问题,以及对应的四个隔离等级。


1.什么是事务


事务处理用来维护数据库的完整性,保证成批的MySQL操作要么完全执行,要么完全不执行。

比如,假设有两个表,账户表money,和支出表pay,那么每一笔支出记录对应就要从余额表中删除一定金额,如果pay插入成功,money修改失败,那么就会造成数据不一致。

MySQL事务操作:

命令 含义
START TRANSACTION; 开启事务。后面的语句处于同一个事务之中
ROLLBACK [TO save_point_name]; 回滚到指定的保留点,或者开启事务之前,结束事务
COMMIT 提交事务,然后结束事务
SAVEPOINT 保留点

示例:

mysql> SELECT * FROM ordertotals;
+-----------+-----------------+-------------+
| order_num | total_not_taxed | total_taxed |
+-----------+-----------------+-------------+
|     20005 |          149.87 |      222.00 |
|     20009 |           38.47 |       40.78 |
|     20006 |           55.00 |       58.30 |
|     20007 |         1000.00 |     1060.00 |
|     20008 |          125.00 |      132.50 |
|     20008 |          125.00 |      132.50 |
|     11111 |          100.00 |      125.00 |
|     11111 |          100.00 |      125.00 |
+-----------+-----------------+-------------+
8 rows in set (0.00 sec)

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

mysql> DELETE FROM ordertotals WHERE order_num = 11111;
Query OK, 2 rows affected (0.00 sec)

mysql> SELECT * FROM ordertotals;
+-----------+-----------------+-------------+
| order_num | total_not_taxed | total_taxed |
+-----------+-----------------+-------------+
|     20005 |          149.87 |      222.00 |
|     20009 |           38.47 |       40.78 |
|     20006 |           55.00 |       58.30 |
|     20007 |         1000.00 |     1060.00 |
|     20008 |          125.00 |      132.50 |
|     20008 |          125.00 |      132.50 |
+-----------+-----------------+-------------+
6 rows in set (0.00 sec)

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

mysql> SELECT * FROM ordertotals;
+-----------+-----------------+-------------+
| order_num | total_not_taxed | total_taxed |
+-----------+-----------------+-------------+
|     20005 |          149.87 |      222.00 |
|     20009 |           38.47 |       40.78 |
|     20006 |           55.00 |       58.30 |
|     20007 |         1000.00 |     1060.00 |
|     20008 |          125.00 |      132.50 |
|     20008 |          125.00 |      132.50 |
|     11111 |          100.00 |      125.00 |
|     11111 |          100.00 |      125.00 |
+-----------+-----------------+-------------+
8 rows in set (0.00 sec)

mysql>

MySQL中默认每个非事务语句都是自动提交的,可以通过 mysql> SET autocommit=0;来设置为不自动提交,这里的提交是相对于客户端程序而言的,未提交时,一个客户端程序仍可以查看到自己修改的内容,断开连接后修改的内容就失效,只有在断开连接前提交,才能在服务器产生永久性修改。

在开启事务之后,必须手动用COMMIT来提交事务。


2.事务的四个特性


原子性:原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。比如转账:支付前money+pay=2000;支付后money+pay2000。

隔离性:事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

持久性:指一个事务一旦被提交,它对数据库中数据的改变就是永久性的。


3.多事务的问题


当多个客户端线程执行数据库操作时,可能出现三种问题:

脏读:一个线程中的事务读到了另一个线程中事务未提交的数据。

不可重复读:一个线程中的事务读到了另一个线程中提交的update的数据,前后两次读到的内容不一致。

虚读:一个线程中的事务读到了另一个线程中提交的insert或delete的数据,前后读到的记录条数不一致。


4.事务的隔离级别


为了解决这些问题,数据库管理软件采用了一些·办法设置了事务的隔离等级。隔离等级越高,数据越安全,但性能越低。

隔离等级 脏读 不可重复读 虚读
READ UNCOMMITTED(未提交读) 可能 可能 可能
READ COMMITTED(提交读)Oracle默认 避免 可能 可能
REPEATABLE READ(可重复读)MySQL默认 避免 避免 可能
SERIALIZABLE(可序列化) 避免 避免 避免

MySQL查看当前数据库的隔离级别命令是:
  mysql> SELECT @@tx_isolation;
更改隔离级别(开启事务之前更改):
  mysql> SET TRANSACTION ISOLATION LEVEL [level_name]


参考文献:


[1] [MySQL]对于事务并发处理带来的问题,脏读、不可重复读、幻读的理解
[2] 《MySQL必知必会》

猜你喜欢

转载自blog.csdn.net/weixin_40255793/article/details/79735665