事务

2019-04-07  本文已影响0人  夜阑w

数据库事务(Database Transaction),是指作为单个逻辑工作单元执行的一系列操作,要么完全执行,要么完全地不执行。

一、事务的四个特性

1. 原子性(Atomicity)

一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚,而在 MySQL 中,恢复机制是通过回滚日志(undo log)实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后在对数据库中的对应行进行写入。

2. 一致性(Consistency)

在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。事务必须使数据库从一个一致的状态变到另外一个一致的状态,也就是执行事务之前和之后的状态都必须处于一致的状态。

3. 隔离性 (Isolation)

数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。也就是说,当多个用户并发访问数据库,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。每个事务的隔离级别其实都比上一级多解决了一个问题。

以上的所有的事务隔离级别都不允许脏写入(Dirty Write),也就是当前事务更新了另一个事务已经更新但是还未提交的数据。 MySQL 使用REPEATABLE READ 作为默认的事务隔离级别。从 RAED UNCOMMITED 到 SERIALIZABLE,随着事务隔离级别变得越来越严格,数据库对于并发执行事务的性能也逐渐下降。

如果没有隔离,会发生的几种问题
脏读(Dirty Read)
不可重复读(NonRepeatable Read)
幻读(Phantom Read)

不同隔离级别的问题

隔离级别 脏读 不可重复读 幻读
未提交 Y Y Y
读提交 N Y Y
可重复读 N N Y
串行化 N N N

4. 持久性(Durability)

持久性是指一个事务一旦被提交了,那么对于数据库中的数据改变就是永久性的,即便是在数据库系统遭遇到故障的情况下也不会丢失提交事务的操作。

二、事务的使用

1. 事务控制语句

2. 事务的处理方法

用 BEGIN, ROLLBACK, COMMIT来实现
直接用 SET 来改变 MySQL 的自动提交模式

SET AUTOCOMMIT=0指当前session禁用自动提交事物,自此句执行以后,每个SQL语句或者语句块所在的事务都需要显示"commit"才能提交事务。START TRANSACTION语句"挂起"自动提交模式的含义是:在事务被提交或回滚之后,该模式将恢复到开始本次事务的 START TRANSACTION语句被执行之前的状态。

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

mysql> INSERT INTO student VALUES  (3,'王五',18,'男');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO score VALUES  (5, 3, 1001, 70);
Query OK, 1 row affected (0.00 sec)

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

mysql> SELECT * FROM student;
+----+------+-----+-----+
| id | name | age | sex |
+----+------+-----+-----+
|  1 | 张三 |  18 | 男  |
|  2 | 李四 |  20 | 女  |
|  3 | 王五 |  18 | 男  |
+----+------+-----+-----+
3 rows in set (0.00 sec)

mysql> SELECT * FROM score;
+----+------------+------------+-------+
| id | student_id | subject_id | score |
+----+------------+------------+-------+
|  1 |          1 |       1001 |    80 |
|  2 |          2 |       1001 |    60 |
|  3 |          1 |       1002 |    70 |
|  4 |          2 |       1002 |  60.5 |
|  5 |          3 |       1001 |    70 |
+----+------------+------------+-------+
5 rows in set (0.00 sec)

3. 隔离级别设置

select @@transaction_isolation;
set  [global | session]  transaction isolation level 隔离级别名称;
上一篇下一篇

猜你喜欢

热点阅读