事务的四种隔离级别和spring传播特性

 

目录

一、事务的四个特征ACID

二、mysql的四种隔离级别

1.Read uncommitted:

2.Read committed:

3.Repeatable read:

4.Serializable:

三、脏读、不可重复读和幻读现象的解释

1.脏读

2.不可重复读

3.幻读

四、5种状态

五、事务的传播特性

1.几种传播特性 

2.需要注意几点

3.传播特性实例


 

一、事务的四个特征ACID

A:Atomicity原子性

C:Consistanty一致性

I:ISolation隔离性

D:Durability持续性

二、mysql的四种隔离级别

其中mysql的四种隔离级别分别是:Read uncommitted(读未提交)、Read committed(读已提交)、Repeatable read(可重复读)、Serializable(序列化)。

1.Read uncommitted:

读取了还未提交的数据,会导致脏读

2.Read committed:

1)能够确保只读取已提交的东西。

2)大部分数据库的默认隔离级别,如sql server、oracle

3)可能会出现不可重复读,即同一个事务多次查询中可能会不同,因为在该事务得其他实例在该实例处理期间,其他实例可能对数据做了新的改动提交,导致多次select结果不一致。

3.Repeatable read:

1)能保证一个事务的多个实例并发读取时看到的结果是一致的,即可重复读取。

2)mysql数据库的默认隔离级别。

3)可能出现幻读,即一个事务在读取数据时,另一个事务在该范围内的插入了其他行,导致再读取该范围的数据时,出现不一致。

4.Serializable:

1)序列化读取,最严格的隔离级别。强制事务排序,在每行数据上加共享锁。

2)可能导致大量的超时和锁竞争

三、脏读、不可重复读和幻读现象的解释

隔离级别\现象脏读不可重复读幻读
Read uncommitted
Read committed
Repeatable read
Serializable

1.脏读

读取了其他事务尚未提交的数据

2.不可重复读

一个事务第二次读取数据时,另一个事务对这些数据做了更新,导致两次结果不一致

3.幻读

一个事务第二次读取数据时,另一个事务在该查询范围内提交了新的数据,导致两次读取数量不一致

四、5种状态

1. 活动状态
事务在执行时的状态叫活动状态。
2. 部分提交状态
事务中最后一条语句被执行后的状态叫部分提交状态。
3. 失败状态
事务不能正常执行的状态叫失败状态。
4. 提交状态
事务在部分提交后,将往硬盘上写入数据,当最后一条信息写入后的状态叫提交状态。进入提交状态的事务就成功完成了。
5. 中止状态
事务回滚并且数据库已经恢复到事务开始执行前的状态叫中止状态。

五、事务的传播特性

1.几种传播特性 

PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启;

2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行;

3. PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常;

4. PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起;

5. PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务;

6. PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常;

7. PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。

2.需要注意几点

1.Spring的@Transaction配置可以在controller,service和dao层的类上声明,但是如果在方法上声明,只对public的方法生效,这是由于spring代理决定的

2.类内部方法自调用,不会触发传播机制,如下,不会触发method2的事务声明,即method2的事务声明无效

class A {
    
    public void method1() {
        method2();
    }
    @Transactional
    public void method2() {
    }
}

3.传播特性实例

1)A调用B,A无事务,B有事务,则B能正常执行成功,A失败

class A {
    
    public void method1() {
        method2();
        dao.deleteById(1)
    } 
}

class B {
    
    @Transactional
    public void method2() {
        dao.deleteById(2)
    }
}

2)方法1调用方法2,均配置事务,若成功都成功,若失败都失败回滚

class A {
    @Transaction
    public void method1() {
        method2();
        dao.deleteById(1)
    } 
}

class B {
    
    @Transactional
    public void method2() {
        dao.deleteById(2)
    }
}

3)方法1默认事务传播特性,方法2为REQUIRES_NEW。若1和2的异常均各自catch,则事务相互独立,1,2均能各自提交成功。否则,如果2的异常影响1,则若2失败,全部失败。如果1异常,2正常,如果1的异常不给catch,也全部回滚,如果1的异常被catch,则2能正常提交。

class A {
    @Transaction
    public void method1() {
        try{
            dao.deleteById(1)
        }catch(Exception e){
        }
        try{
            method2();
        }catch(Exception e){
        }
    } 
}

class B {
    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void method2() {
        try{
            dao.deleteById(2)
        }catch(Exception e){
        }
    }
}

4)嵌套事务,JpaDialect不支持savepoint,所以没做过多验证,根据其他大神验证的结果是,外部事务失败影响内部,内部失败不影响外部。即内部事务回滚不会导致外部事务回滚,外部事务回滚会导致内部事务回滚。

 

参考:https://www.cnblogs.com/protected/p/6526857.html

http://blog.chinaunix.net/uid-7345847-id-2643947.html

https://blog.csdn.net/chudaxiakkk/article/details/80889494

https://blog.csdn.net/spyunknow/article/details/105666744

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值