事务的特性


事务出现在多个场景中,在一些交易场景中事务显得特别重要。这个也是面试中肯定会遇到的一个问题,所以聊聊我理解的事务。

事务的定义

事务是指一系列操作被当做一个单独的工作单元来执行,要么全部失败,要么全部成功要么全部回滚到原始状态,可以确保数据的一致性,完整性和可靠性。
具备四个特性:(ACID)
举个例子一个事务包含两个操作,a=1,b=2 a++ b++

  1. 原子性(Atomicity):,要确保事务的完整进行,就需要保证a++和b++这两个操作同时完成,或者同时失败回退。这两个操作也就是最低单元不可再分了,这个就叫做原子性;
  2. 一致性(Consistency):a++和b++两个操作是有执行时间的,那如果a++的时候有别的操作需要访问a这个时候应该a是原始的1还是++后的2呢?一般来说在这个时候访问a a的值是1,b的值是2,当两个操作结束以后a=2,b=3.这就强调了在事务的开始和结束状态的一致性,中间态是不能被别的访问到的,这就是一致性。
  3. 隔离性(Isolation):那如果有另一个事务a=1 c=3 ,a-- c++,那这两个事务之间应该是不影响的,必须在第一个事务结束以后才能有第二个事务进行,这个是隔离策略的不同。
  4. 持久性(Durability):当整个操作结束以后,整个的结果不会改变。一旦事务提交成功,其所做的更新将永久保存在系统中,即使系统发生故障也不会丢失。持久性确保了事务的可靠性和可恢复性。 这个比较好理解就不说了。

事务的隔离级别

事务需要数据库的支持才能使用,我常用的数据库有mysql和pg 高斯,mysql的存储引擎有InnoDB和mySIAM,InnoDB是支持事务的,上面也说了事务的隔离性,总体来说事务的隔离级别有三种:读已提交,可重复读,串行化,主要解决了脏读,幻读,不可重复读这三个问题,mysql的默认隔离级别是可重复读,pg的默认隔离级别是读已提交。
脏读:在最低的隔离级别下,会发生可重复读。事务A可以读取到事务B未提交的事务,读已提交的意思就是事务A只能读取事务B已经提交的事务,解决了脏读问题。
在这里插入图片描述
幻读:幻读是指在同一事务内,对同一范围的数据进行两次查询,但查询的结果集不一致,串行化可以解决幻读问题。
在这里插入图片描述
不可重复读 一个事务对一个数据的两次查询的结果不一致,当事务 A 执行第一次查询时,数据库会为其创建一个读取视图,记录了查询时可见的数据。但在事务 A 执行第二次查询时,由于事务 B 修改了数据并提交,事务 A 的读取视图已经过期,因此读取到了不一样的数据。
其实这块我有点困惑,事务A的两次读取应该是原子的,两个读取是同时进行的,这个仅仅代表对于事务A自身来说,两个读取是原子的,而对于整个事务体系来说,别的事务B修改中间的某一个数据是允许的
在这里插入图片描述

spring中是如何管理事务的

@EnableTransactionManagement   开启事务
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
@Transactional(propagation = Propagation.REQUIRED)  具体的事务的执行单位
@Service
@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
public class ItemServiceImpl implements ItemService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public String updateValue(String object)  {
         userMapper.updateStatus(object+"");
         return "";
    }

    @Override
    public String getValue(String sss) {
        return userMapper.getValue(sss);
    }

    @Override
    public void updateStatus(String sss) {
         userMapper.updateStatus(sss);
    }
}

spring中事务的传播机制

  1. PROPAGATION_REQUIRED:默认的Spring事物传播级别,若当前存在事务,则加入该事务,若
    不存在事务,则新建一个事务。
  2. PAOPAGATION_REQUIRE_NEW:若当前没有事务,则新建一个事务。若当前存在事务,则新建
    一个事务,新老事务相互独立。外部事务抛出异常回滚不会影响内部事务的正常提交。
  3. PROPAGATION_NESTED:如果当前存在事务,则嵌套在当前事务中执行。如果当前没有事务,
    则新建一个事务,类似于REQUIRE_NEW。
  4. PROPAGATION_SUPPORTS:支持当前事务,若当前不存在事务,以非事务的方式执行。
  5. PROPAGATION_NOT_SUPPORTED:以非事务的方式执行,若当前存在事务,则把当前事务挂
    起。
  6. PROPAGATION_MANDATORY:强制事务执行,若当前不存在事务,则抛出异常.
  7. PROPAGATION_NEVER:以非事务的方式执行,如果当前存在事务,则抛出异常。

事务的传播机制主要关注事务之间的嵌套关系和边界范围,用于控制事务的创建、加入和提交等操作;而隔离级别主要关注并发事务之间的可见性和影响,用于解决并发访问数据可能引发的问题。两者都是事务管理和并发控制中的关键概念,但目标和应用场景略有不同。

spring中事务失效

1.检查你方法是不是public的(只有Public方法才能开启事务)
2.检查你的异常类型是不是unchecked异常(默认Error和RuntimeException事务回滚)。可以参考一下异常的分类
3.检查异常是不是被catch住了(当异常被捕获后,并且没有再抛出,那么事务是不会回滚的。)
4.检查类有没有被Spring管理(方法被标注了@Transactional,但是类没有注解,没有被Spring管理也不会生效)
5.是用动态代理实现的 所有就需要关注动态代理

分布式事务解决方案

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值