1、数据库事务基本特征
1.原子性
2.一致性
3.隔离性
4.持久性
2、第一类丢失更新
假设要更新一个计数器count=10,事务1将count+1(即update count=11),事务2也将count+1,当事务1提交 成功,事务2提交成功,事务2失败回滚,回滚到最初态count=10,事务1的更新将被丢失
3、第二类丢失更新
假设要更新一个计数器count(10),事务1将count+1,事务2也将count+1,那么两个事务提交后,count更新为11和意想的12不一致
注意:设置隔离等级并不能解决第二类更新丢失,隔离等级决定的是事务查询更新处于怎么样的环境,无论隔离等级如何,
第二类更新丢失总是存在,因为它是以后者覆盖前者,和隔离时的可见性没有必然联系。MySQL的update是互斥的,即一个在update(可能是事务),另一update必须阻塞直到其他update完成(事务提交),这样一来,无论隔离等级如何,使用count=count+1这种方式更新是不会出现第二类更新
二、隔离等级
1、查询当前隔离等级
Select @@tx_isolation/@@transaction_isolation;
2、设置当前会话隔离等级
Set session transaction isolation level isolation_level(read uncommitted, read committed, repeatable read, serializable;
3、read uncommitted读未提交
在一次事务中,若其他事务产生了更新或插入(尽管未提交),该事务查询可见更新或插入
1、在进行数据库操作的两个事务,事务1( READ-COMMITTED)进行update操作,事务2(READ-UNCOMMITTED)进行查询操作(事务1提交前),事务2能成功查询到事务1的未提交更新
事务1:
mysql> select @@tx_isolation;
+---------------------------+
| @@tx_isolation |
+---------------------------+
| READ-COMMITTED |
+---------------------------+
1 row in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+-----------+-----+
| id | user_name | sex |
+----+-----------+-----+
| 1 | jyin | 1 |
| 2 | mike | 1 |
| 3 | john | 1 |
+----+-----------+-----+
3 rows in set (0.00 sec)
mysql> update user set sex=2 where id=3;
Query OK, 1 row affected (0.01 sec)
事务2:
mysql> select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+-----------+-----+
| id | user_name | sex |
+----+-----------+-----+
| 1 | jyin | 1 |
| 2 | mike | 1 |
| 3 | john | 2 |
+----+-----------+-----+
2、反之,事务1无法查询到事务2的未提交更新
事务1(事务2进行update操作后)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+-----------+-----+
| id | user_name | sex |
+----+-----------+-----+
| 1 | jyin | 1 |
| 2 | mike | 1 |
| 3 | john | 1 |
+----+-----------+-----+
3 rows in set (0.00 sec)
事务2
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update user set sex=2;
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3 Changed: 3 Warnings: 0
4、read committed读已提交
在一次事务中,若其他事务产生了更新插入提交,该事务查询可见提交
5、repeatable read可重读
在一次事务中,第一次查询和第二次查询结果一致(中间无主动更新或插入),对其他事务更新插入提交不可见
事务1
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+-----------+-----+
| id | user_name | sex |
+----+-----------+-----+
| 1 | jyin | 1 |
| 2 | mike | 1 |
| 3 | john | 2 |
+----+-----------+-----+
3 rows in set (0.01 sec)
mysql> update user set sex=1 where id=3;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
在事务1提交前进行事务2(repeatable read)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+-----------+-----+
| id | user_name | sex |
+----+-----------+-----+
| 1 | jyin | 1 |
| 2 | mike | 1 |
| 3 | john | 2 |
+----+-----------+-----+
3 rows in set (0.00 sec)
然后事务1提交,事务2再次进行查询
mysql> select * from user;
+----+-----------+-----+
| id | user_name | sex |
+----+-----------+-----+
| 1 | jyin | 1 |
| 2 | mike | 1 |
| 3 | john | 2 |
+----+-----------+-----+
3 rows in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;
+----+-----------+-----+
| id | user_name | sex |
+----+-----------+-----+
| 1 | jyin | 1 |
| 2 | mike | 1 |
| 3 | john | 1 |
+----+-----------+-----+
3 rows in set (0.00 sec)
6、serializable
在一次事务中,在进行更新或插入操作时,其他事务开始更新或插入,该事务将被阻塞,直到其他事务被提交
事务1
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert user(user_name, sex) values('cherry', 2);
Query OK, 1 row affected (0.01 sec)
在提交前进行事务2
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user;(在此阻塞直到事务1提交才能完成查询)
+----+-----------+-----+
| id | user_name | sex |
+----+-----------+-----+
| 1 | jyin | 1 |
| 2 | mike | 1 |
| 3 | john | 1 |
| 4 | cherry | 2 |
+----+-----------+-----+
4 rows in set (11.78 sec)
如果事务2在事务1进行插入或更新操作前进行查询,然后事务1进行插入或更新,事务1会被阻塞直到事务2提交
6、隔离等级和可能发生的现象
|
脏读
|
不可重复读
|
幻读
|
未提交读
|
√
|
√
|
√
|
读写提交
|
×
|
√
|
√
|
可重复读
|
×
|
×
|
√
|
串行化
|
×
|
×
|
×
|