MySQL事务

1.事务

1.事务特性--ACID

 (1)原子性(Atomicity):原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。

(2)一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

  拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。

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

  即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

  关于事务的隔离性数据库提供了多种隔离级别,稍后会介绍到。

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

2.事务隔离级别:

read uncommitted:可以读到未提交的事务结果
read committed:只能读已提交事务的结果
repeatable reads:可以读到开启事务时的值
serializable:两个事务同时发生,必定是有先后的

3.实践操作的准备

使用Join and Group中两个表,向product表中新添一个字段count,用来记录产品数量

2.Read Commit

预热:查询一下当前数据库的事务隔离级别,保证事务隔离级别是read-commited

我的数据库是Mysql5.5,默认事务隔离级别是repeatable-read,所以将其修改为read-commited

1.首先开启两个事务--事务A,事务B(注意这里如果使用可视化界面,例如Heidi,可能两个窗口并不是真正的开启了两个事务,所以建议使用cmd来测试)

开启事务A -> 将自动提交设为否(似乎5.5以上版本事务隔离级别高,不自动提交) -> 查询productId=4的count

事务A:

开启事务B,执行与事务A同样的操作

事务B:

2.在事务B中操作,将productId=4的count更改为49,但是不提交事务

事务B:

3.此时在事务A中查询一下count值,看在事务B更改数据但是未提交的情况下,事务A是否能查看到更新后的数据

事务A:

结果:事务A不能查看到事务B未提交的数据

4.将事务B提交,操作事务A,看是否能查询到更新后的数据

事务A:

结果:事务B提交后,事务A能查询到更新后的数据了

结论:当事务隔离级别为read-commited时,一个事务只能读取到另一事务已提交的数据

 3.Repeatable-read

预热:查询并将事务隔离级别修改为repeatable-read,将数据库中count字段初始化为50

1.分别在开启事务A,事务B

事务A:

事务B:

2.在事务B端更改count值,但是不提交事务

事务B:

操作事务A查询count,发现查询结果没变

事务A:

3.提交事务B,并且操作事务A查看count,发现查询到的count值依然没变

事务B:

事务A:

结论:当事务隔离级别为repeatable-read时,一个事务只能读到开启本事务时读到的数据,无法读取其他事务更新的数据

4.Serializable

预热:查询并将事务隔离级别更改为serializable,将product表中count更改为50

1.分别开启事务A,事务B

2.在事务B端执行更新操作

事务B:发现没有一直处于执行中,并没有执行成功

2.将事务A提交后,发现事务B更新成功

事务A:

事务B:

3.再提交事务B,操作事务A

事务B:

事务A:

结论:在serilizalbe级别下,select语句不仅会开启事务,还会降数据锁上,只允许其他事务查询,不允许更改

 5.For update

事务隔离级别没必要提升到serilizable,只需要使用read-committed,select语句加for update即可

预热:将事务隔离级别更改为read-committed

 1.开启事务A,并将查询语句中加入for update

事务A:

事务B:

结果:只有当事务A提交之后,事务B才能查询到数据

结论:在select语句中加入for update时,只有当次事务提交之后,其他事务才能查询数据,for update会将数据加锁,防止其他事务操作发生数据不一致

 6.乐观锁

在语句中加入版本控制,如果版本是当前版本则可以进行修改,否则进行回滚,还有加锁可是很浪费时间的哦

转发一篇文章悲观锁和乐观锁;,自己很喜欢的公众号---码农翻身

7.例题

原文地址:https://www.cnblogs.com/Hangtutu/p/8016663.html