原子性(Atomicity)
一组操作·要么全成功,要么全失败。
一致性(Consistency)
保证数据的正确性,合理性,完整性。事务在完成时,必须使所有的数据都保持一致状态
例如,在一次转账过程中,从某一账户中扣除的金额必须与另一账户中存入的金额相等。
隔离性(Isolation)
持久性(Durability)
二、事务的隔离级别
一般数据库中,有四种隔离级别
如上图,四种隔离级别分别实现了不同的功能,看是级别越高也代表着需要的锁越多,更容易产生阻塞。
接下来通过实验介绍这几种读
(1)脏读
把隔离级别调为read-uncommitted
+---------------+------------------+
| Variable_name | Value |
+---------------+------------------+
| tx_isolation | read-uncommitted |
+---------------+------------------+
1 row in set (0.00 sec)
会话1:
Empty set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected (0.00 sec)
还没有提交
会话2:
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 1 | xiaohong | 99 |
+------+----------+-------+
1 row in set (0.00 sec)
会话2可以直接读到会话1还没有提交的数据。
(2)不可重复读
+---------------+------------------+
| Variable_name | Value |
+---------------+------------------+
| tx_isolation | READ-COMMITTED |
+---------------+------------------+
1 row in set (0.00 sec)
会话1:
Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected (0.00 sec)
会话2:
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 1 | xiaohong | 99 |
+------+----------+-------+
1 row in set (0.00 sec)
会话1:
Query OK, 0 rows affected (0.00 sec)
会话2:
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 3 | xiaohong | 99 |
+------+----------+-------+
1 row in set (0.00 sec)
会话2第一次只读到id的值是1,但以为会话1提交,会话2第二次读到id的值是3.
(3)幻读
会话1:
Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected (0.00 sec)
会话2:
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 1 | xiaohong | 99 |
+------+----------+-------+
1 row in set (0.00 sec)
会话1:
Query OK, 0 rows affected (0.00 sec)
会话2:
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 3 | xiaohong | 99 |
| 2 | xiaoming | 65 |
+------+----------+-------+
2 rows in set (0.00 sec)
会话2第一次只读到1条数据,但以为会话1提交,会话2第二次读到两条记录
ps:不可重复读是因为数据的update导致,而幻读是因为数据的delete或者insert导致
三、MysqL中的事务
那怎么禁用事务自动提交呢?如下:
session级别:
set autocommit=off;
局级别:
方法一:set global init_connect='set autocommit=0';
[MysqLd]
init_connect='set autocommit=0';
也可以通过begin开启一个事务,再通过commit提交;
MysqL中的innodb的事务默认隔离级别是Repeatable read(可重复读),但是它不是普通的Repeatable read,它在可重复读的基础上避免了幻读。是通过臭名昭著的gop锁实现不可重复读。
myql通过tx_isolation决定事务隔离级别 ,可以查看当前的参数
+---------------+----------------+
| Variable_name | Value |
+---------------+----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+----------------+
1 row in set (0.00 sec)