【MySQL】事物

目录

1、事物定义

2、事物的特性( A C I D )

(1)事务的原子性(Atomic)

(2)事务的一致性(Consistency)

(3)事务的隔离性(Isolation)

(4)事务的持久性(Durability)

3、事务的隔离级别(隔离性)

1)多个事务同时操作时可能产生的问题

2)解决办法

4、操作事物的步骤

1、设置事务的隔离级别

2、开启事务

3、书写组成事务的sql语句

4、事物的结束与回退

5、简述步骤


1、事物定义

一个事务是由一条或者多条对数据库操作的SQL语句所组成的一个不可分割的单元,只有当事务中的所有操作都正常执行完了,整个事务才会被提交给数据库;如果有部分事务处理失败,那么事务就要回退到最初的状态,或者回到事务操作的任何一个状态。因此,事务要么全部执行成功,要么全部失败。

2、事物的特性( A C I D )

(1)事务的原子性(Atomic)

事务是一个不可分割的整体,事务必须具有原子特性,及当数据修改时,要么全执行,要么全不执行,即不允许事务部分的完成。 (这里主要说的是你最后提交数据要么整体提交要么退回到一个保存点 ,不可能提交一部分)。

(2)事务的一致性(Consistency)

一个事务执行之前和执行之后,数据库数据必须保持一致性状态。数据库的一致性状态必须由用户来负责,由并发控制机制实现。就拿网上购物来说,你只有让商品出库,又让商品进入顾客的购物车才能构成一个完整的事务!由于并发操作带来的数据不一致性包括读脏数据(脏读),不可重复读和虚读(幻读)。

(3)事务的隔离性(Isolation)

当两个或者多个事务并发执行时,为了保证数据的安全性,将一个事物内部的操作与其它事务的操作隔离起来,不被其它正在执行的事务所看到,例如对任何一对事务T1和T2,对T1而言,T2要么在T1开始之前已经结束,要么在T1完成之后再开始执行。隔离性使得每个事务的更新在它被提交之前,对其它事务都是不可见的。

(4)事务的持久性(Durability)

事务完成以后,DBMS(数据库管理系统,这里是Mysql)保证它对数据库中的数据的修改是永久性的(当你commit后事物也是不能修改),即使数据库因为故障出错,也应该能够恢复数据!

3、事务的隔离级别(隔离性)

1)多个事务同时操作时可能产生的问题

(1)脏读(Dirty Read)

脏读(Dirty Read):一个事务读取了另一个事务未提交的数据。(在rollback前后看到的数据是不一样的)例如当事务A和事务B并发执行时,当事务A更新后,事务B查询读取到A尚未提交的数据,此时事务A回滚,则事务B读到的数据就是无效的脏数据。(事务B读取了事务A尚未提交的数据)

  • 银行转账问题

小明账户上有50元钱,小红向小明账户转账50元,即小明账户此时应该有100元,但是,小红此时又不想给小明转了,此时还没有进行 ROLLBACK 或者 COMMIT;此时,小明查看了自己的账户,发现此时账户里有100元钱,接着小红执行 ROLLBACK 回退至未转账状态,小明再次查询账户,发现此时账户内只有50元,我们称这种状态为“脏读”,这种事情小明可能就忍受不了,估计就要问银行这是啥情况,所以银行就应该避免“脏读”。

(2)不可重复读(NonRepeatable Read)

不可重复读(NonRepeatable Read): 一个事务的操作导致另一个事务前后两次读取到不同的数据。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A更新操作更改事务B查询到的数据,此时事务B再次去读该数据,发现前后两次读的数据不一样。(事务B读取了事务A已提交的数据)

  • 超市秒杀问题

超市11.11日打折促销,一位顾客在23:59:59进行结账,他买了好多东西,当收银员在开启结账时开启事务读取数据库中的商品价目,第一个商品读取到的是促销价目表,而定时系统在12:00整时启动系统进行价目表的更新操作,更改完数据后进行 COMMIT 操作,此时后面的商品所读取的商品价格是11.12日的正常商品价格,我们称这种情况为“不可重复读”,这种情况顾客是不能允许的,或许收银员手快点就可以避免,就会产生误会,所以超市秒杀应避免这种情况发生。

(3)虚读(Phantom Read)/幻读

虚读(Phantom Read)/幻读:一个事务的操作导致另一个事务前后两次查询的结果数据量不同。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A新增或者删除了一条满足事务B查询条件的记录,此时事务B再去查询,发现查询到前一次不存在的记录,或者前一次查询的一些记录不见了。(事务B读取了事务A新增加的数据或者读不到事务A删除的数据)

  • 银行存款问题

小红账户本身只有人民币一种货币类型,此时小明开启事务想要给小红账户里面存储美元这种货币,币;与此同时,小强查看小红账户也发现小红账户中不存在美元这种货币类型,也开启事务进行存款。此时,小明完成操作,执行 COMMIT 操作,而小强在进行 COMMIT 时提示美元类型已经创建的错误,但是小强看的是小红账户上没有,我们称这种情况为“虚读/幻读”。但是实际小明存的时候系统已经insert了,小强这里系统只需update就可以,但是系统select后发现小强这里还是要insert,这就会出错。

2)解决办法

为解决这三种问题,我们可以利用事务的隔离性来进行。根据不同场景设置不同的隔离级别。只要将隔离级别设置能满足上述三个问题就可以,也不是隔离级别越高越好,越高则效率越低,只要能满足需求即可。

不同的隔离级别解决不同的问题,而主要有四种隔离级别(不包括不支持事务的情况)。

隔离级别脏读不可重复读幻读
未提交读可以可以可以
已提交读不可以可以可以
可重复读不可以不可以可以
串行化/可序列化(效率最低)不可以不可以不可以

 

查看设置隔离级别常见的英文:

  1. TRANSACTION_NONE。 表示不支持事务
  2. TRANSACTION_READ_UNCOMMITTED。未提交读。
    说明在提交前一个事务可以看到另一个事务的变化。这样读”脏”数据,不可重复读和虚读都是被允许的。
  3. TRANSACTION_READ_COMMITTED。已提交读。
    说明读取未提交的数据是不允许的。这个级别仍然允许不可重复读和虚读产生。
  4. TRANSACTION_REPEATABLE_READ。可重复读。
    说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。
  5. TRANSACTION_SERIALIZABLE。可序列化/串行化。
    是最高的事务级别,它防止读脏数据,不可重复读和虚读,可理解为完全解锁的情况。

4、操作事物的步骤

存储引擎必须要切换到InnoDB引擎下

1、设置事务的隔离级别

(1)查看事务的隔离级别

mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.00 sec)

(2)根据需求设置事务的隔离级别

set session transaction isolation level READ COMMITTED;

如下4种分别对应4种隔离级别:

Read uncommitted (未提交读)、Read committed(已提交读 )、Repeatable read(可重复读)、 Serializable (可序列化/串行化)。

2、开启事务

(1)查看MySQL是否已经关闭自动提交

mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)

0表示手动提交事务 ,1表示自动提交事务,默认一般为1。这里使用 set autocommit = 0 操作,设置事务提交方式为手动提交事务。

(2)开启事物

begin 或 start transaction显示地表示一个事务的开启(可写可不写)。

3、书写组成事务的sql语句

 

4、事物的结束与回退

如果事务执行过程中有bug  rollback/rollback  to;如果没有任何bug我们就commit;

其中:

  • commit;当组成事务的所有SQL语句都执行成功,调用commit提交一个事务。
  • rollback;如果在执行事务的过程当中有一个事务执行失败,回滚一个事务到初始的位置。
  • savepoint p; 设置一个名字为p的保存点
  • rollback to p; 事务回滚到保存点p,而不是回滚到初始状态

commit和rollback是事务结束的两种方式

5、简述步骤

  1. 设置隔离级别。 将事务的级别设置为4种中的一种。
  2. 开启事务
  3. begin
  4. 书写组成事务的sql语句
  5. 如果事务执行过程中有bug rollback/rollback to;如果没有任何bug我们就commit;

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值