Mysql的事务

一、MySQL事务及ACID特性

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

特点:
1、事务是一组SQL语句的执行,要么全部成功,要么全部失败,不能出现部分成功,保证事务执行的原子操作。
2、事务的所有SQL全部执行成功,才能提交事务(commit),把结果写到磁盘上。
3、事务执行过程中,有的SQL出现错误,那么事务要回滚(rollback)到最初的状态。

事务的ACID特征:
事务的原子性(Atomic):

事务是一个不可分割是整体,事务必须具有原子特征, 即当数据修改时,要么全部执行,要么全部不执行,即不允许事务部分执行

事务的一致性(Consistency):

一个事务执行之前和执行之后,数据库数据必须保证一致性状态,一致性状态是有用户负责使用并发控制机制实现。
举例:购买商品添加至购物车,商品库存减少和商品添加至购物车是一个完整性事务。 并发控制不当会带来数据不一致性包括:脏数据、虚度(幻读)

事务的隔离性(Isolation):

当两个或者多个事务并发处理时,为了保证数据的安全性,将一个事务的内部操作与其他事务的操作隔离起来, 不被其他正在执行的事务所看到。

事务的持久性 (Durability):

事务完成之后,对数据库中的数据修改时永久性的,即使数据库音故障出错,也因该能回复数据

二、事务的四个隔离级别

事务不经隔离,并发执行事务会出现的问题:

1、脏读(Dirty READ):一个事务读取了另一个事务未提交的数据
例:当事务A和事务B并发执行时,当事务A更新数据后,事务B查询到A尚未提交的数据,此时事务A回滚,
则事务B读到的数据就是无效的脏数据(事务B读取了事务A尚未提交的数据)

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

3、虚读(Phantom READ): 一个事务的操作导致另一个事务前后两次查询的结果数量不同

举例:
A事务读取了B事务已经提交的新增数据。和不可重复读的区别,这里是新增,不可重复读是更改(或删除)。 这两种情况对策是不一样的,对于不可重复读,只需要采取行级锁防止该记录数据被更改或删除,然而对于幻读必须加表级锁,防止在这个表中新增一条数据。

  • 未提交读

    读未提交,即能够读取到没有被提交的数据,所以很明显这个级别的隔离机制无法解决脏读、不可重复读、幻读中的任何一种。

  • 已提交读

    读已提交,即能够读到那些已经提交的数据,自然能够防止脏读,但是无法限制不可重复读和幻读

  • 可重复读

    可重复读,读取了一条数据,这个事务不结束,别的事务就不可以改这条记录,这样就解决了脏读、不可重复读的问题,

  • 串行化

    串行化,多个事务时,只有运行完一个事务之后,才能运行其他事务。

jdbc 下Connection对象,定义了5种不同隔离级别:

1、Transaction_None:表示不支持事务
2、Transaction_Read_Uncommitted:未提交读。 说明一个在提交前一个事务可以看到另一个事务的变化, 这个可以读脏数 据, 不可重复读,虚读都是被允许存在的
3、Transaction_Read_Committed:已提交读 说明读取未提交的数据是不被允许的,不可重复读、虚读是会出现的
4、Transaction_Repeatable_read:可重复读 事务保证能够读取相同的数据而不会失败,虚读数据还是会出现的
5、Transaction_serializable:可序列化/串行化, 最高事务级别,防止脏读、不可重复读、虚读


注意:事务隔离级别越高,为了避免冲突所花费非性能也就越多,并不是界别越高越好

三、Mysql锁机制

MySQL大致可归纳为以下3种锁:

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

表锁:对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;对MyISAM表的写操作,则会阻塞其他用户对同一表的读和写请求;

读读:可以允许

读写:不允许

写写:不允许

InnoDB采用行锁

InnoDB实现了以下两种类型的行锁。

共享锁(s):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
排他锁(X):允许获取排他锁的事务更新数据,阻止其他事务取得相同的数据集共享读锁和排他写锁。

InnoDB行锁是通过索引上的索引项来实现的。InnoDB这种行锁实现特点意味者:只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将使用表锁!

对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁;对于普通SELECT语句,InnoDB不会加任何锁。

间隙锁(Next-Key锁)

当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁。
比如会给between and 中间所有存在或者不存在数据加锁。可以防止幻读。
MVCC(无锁实现) 多版本并发控制机制 --》给每一个事务维护一个数据最初的快照

1,未提交读:

  读读/读写:事务不做任何隔离操作

   写写:获取记录的排他锁,不能同时进行,除非一个事务 提交或回滚

2,已提交读:

(其他事务提交或者回滚,它会立即读到)

 读读:事务读的是事务最初的快照 mvcc机制

 读写:读的是快照数据,写的也是快照数据 mvcc机制

 写写:获取记录的排他锁,不能同时进行,除非一个事务 提交或回滚

3,可重复读 (jdbc默认隔离级别)

 读读:事务读的是快照数据 mvcc机制

 读写:读的是快照数据,写的也是快照数据(除非当前事务提交或回滚,否则访问的都是快照数据) mvcc机制

 写写:获取记录的排他锁,不能同时进行,除非一个事务 提交或回滚

4,串行化

        读读 :共享锁多个事务可以同时获取

        读写 : 共享锁和排它锁

        写写 : 排它锁和排它锁

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值