事务 隔离级别 脏读 不可重复 幻读

 

 事务的定义

事务,就是一组操作数据库的动作集合。

如果一组 处理步骤 全部发生或者一步也不执行,我们称该组处理步骤为一个事务。

当所有的步骤像一个操作一样被完整地执行,我们称该事务被提交。

由于其中的一部分或多步执行失败,导致没有步骤被提交,则事务必须回滚到最初的系统状态。

二、事务的并发问题

1、脏读:事务A读取了事务B更新、未提交的数据,然后B回滚操作,那么A读取到的数据是脏数据(没有用的数据)

2、不可重复读:事务 A 多次读取同一数据,结果读取的数据不一致,也就是说不支持重复读,重复读会有错误。      原因是 事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据不一致。

3幻读:事务A读取所有工资为5000的人数为10人。此时,事务B插入一条工资也为5000的记录。这,事务A再次读取工资为5000的员工,记录为11人。此时产生了幻读。  需要表锁才能隔离,所以大都数数据库都 没有将幻读隔离。

  小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

 

三、MySQL事务隔离级别


事务隔离级别

读取速度

脏读

不可重复读

幻读

含义

读未提交(read-uncommitted

效率高,

但是不用

允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读

不可重复读级别的read-committed

orcale

采用的级别

允许在并发事务已经提交后读取。可防止脏读,但幻读和 不可重复读仍可发生

可重复读(repeatable-read

mysql

的级别

对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读仍可能发生。

串行化(serializable

隔离级别最高

 

安全,效率最低

完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的。



 事务的隔离级别 ,是由数据库提供的 ,并不是所有数据库都支持四种隔离级别

       MySQL : READ_UNCOMMITTEDREAD_COMMITTEDREPEATABLE_READSERIALIZABLE (默认 REPEATABLE_READ

       Oracle READ_UNCOMMITTEDREAD_COMMITTEDSERIALIZABLE(默认 READ_COMMITTED

查询当前级别 mysql>select @@tx_isolation


spring 五种隔离级别

第一种是默认的,ISOLATION_DEFAULT  使用数据库默认的事务隔离级别. 另外四个与JDBC的隔离级别相对应;

第二种是ISOLATION_READ_UNCOMMITED, 会产生脏读, 不可重复读, 幻读

第三种是ISOLATION_READ_COMMITED, 可以防止脏读, 但是会发生不可重复读和幻读

第四种是ISOLATION_REPEATABLE_READ, 可以防止脏读和不可重复度, 但是会产生幻读

第五种是ISOLATION_SERIALIZABLE,spring事物的最高隔离级别, 可以防止脏读,不可重复读, 幻读的发生, 但是这种隔离级别极大的牺牲了性能.

 

其中spring七个事物传播属性:
PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,
则进行与PROPAGATION_REQUIRED类似的操作。

 


补充:

1SQL规范所规定的标准,不同的数据库具体的实现可能会有些差异

2mysql中默认事务隔离级别是可重复读时并不会锁住读取到的行

3、事务隔离级别为读提交时,写数据只会锁住相应的行

4、事务隔离级别为可重复读时,如果有索引(包括主键索引)的时候,以索引列为条件更新数据,会存在间隙锁间隙锁、行锁、下一键锁的问题,从而锁住一些行;如果没有索引,更新数据时会锁住整张表。

5、事务隔离级别为串行化时,读写数据都会锁住整张表

6、隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大,鱼和熊掌不可兼得啊。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
幻读脏读不可重复读是数据库中常见的并发控制问题。 1. 幻读(Phantom Read):幻读是在同一个事务中,多次执行同一个查询语句,但结果集却不同的现象。通常是由于并发事务中的插入、更新或删除操作导致的。例如,一个事务在查询时得到了某个范围内的数据行,并且在此事务提交之前,其他事务插入了一个新的符合该查询条件的数据行,那么在此事务再次查询时,会返回多出来的这条新数据行,这就是幻读。 2. 脏读(Dirty Read):脏读是指一个事务读取了另一个事务未提交的数据。当一个事务读取到另一个未提交事务的数据后,如果未提交事务回滚或修改了该数据,那么读取到的数据就是脏数据。脏读可能导致错误的判断和处理。 3. 不可重复读(Non-repeatable Read):不可重复读是指在同一个事务中,多次执行同一个查询语句,但结果集却不一致的现象。通常是由于并发事务中的更新或删除操作导致的。例如,一个事务在查询时得到了某个数据行,并且在此事务提交之前,其他事务修改或删除了该数据行,那么在此事务再次查询时,会得到与之前不同的结果,这就是不可重复读。 为了解决这些问题,可以采用以下并发控制方法: - 锁机制:通过给数据对象加锁来控制并发访问。 - 事务隔离级别:通过设置事务隔离级别来控制不同事务之间的可见性。 - MVCC(Multi-Version Concurrency Control):通过为每个事务创建一个独立的数据版本来避免并发冲突。 - 乐观并发控制:通过版本号或时间戳等方式来检测并发冲突,减少锁的使用。 这些方法可以根据具体情况选择并结合使用,以确保数据库的一致性和并发性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值