经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » SQL语言 » 查看文章
数据库事务
来源:cnblogs  作者:Atua  时间:2019/9/10 10:49:02  对本文有异议

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、隔离等级和可能发生的现象

 

脏读

不可重复读

幻读

未提交读

读写提交

×

可重复读

×

×

串行化

×

×

×

原文链接:http://www.cnblogs.com/Atua/p/11459823.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号