文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

一文搞清楚Spring事务

2023-05-17 11:03

关注

什么是Spring事务?

Spring事务是指在Spring框架中对于数据库操作的一种支持,它通过对一组数据库操作进行整体控制来保证数据的一致性和完整性。Spring事务可以保证在一组数据库操作执行时,要么所有操作都执行成功,要么所有操作都回滚到之前的状态,从而避免了数据不一致的情况。

Spring事务实现方式

Spring事务可以通过编程式事务和声明式事务两种方式来实现。编程式事务需要在代码中手动控制事务的开始、提交和回滚等操作,而声明式事务则是通过在配置文件中声明事务的切入点和通知等信息来自动控制事务的行为。

Spring编程式事务

Spring编程式事务需要在代码中获取事务管理器,并通过该事务管理器获取事务对象,然后使用该事务对象来控制事务的开始、提交和回滚等操作。

public void transferMoney(Account fromAccount, Account toAccount, double amount) {
    TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
    try {
        fromAccount.withdraw(amount);
        toAccount.deposit(amount);
        transactionManager.commit(status);
    } catch (Exception e) {
        transactionManager.rollback(status);
    }
}

在上面的代码中,首先通过transactionManager.getTransaction方法获取事务对象status,然后在try块中执行转账操作,最后通过transactionManager.commit(status)提交事务。如果在转账操作中发生了异常,则会通过transactionManager.rollback(status)回滚事务。

编程式事务的优点是灵活性高,可以根据具体的业务需求来灵活控制事务的行为。不过缺点是代码冗长,可读性差,而且容易出现错误。

Spring声明式事务

Spring声明式事务需要在配置文件中声明事务管理器、事务通知等元素,然后在需要使用事务的方法上添加事务切面的注解即可。

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="transferMoney" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="transferPointcut" expression="execution(* com.example.TransferService.transferMoney(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="transferPointcut"/>
</aop:config>

在上面的配置文件中,首先声明了事务管理器transactionManager,然后定义了事务通知txAdvice,该通知会在transferMoney方法执行时进行事务管理。最后通过aop:configaop:advisor来将txAdvice应用于transferPointcut定义的切入点上。

声明式事务的优点是通过配置文件来管理事务,避免了在代码中手动控制事务的繁琐和容易出错的问题。不过缺点是灵活性较差,不能根据具体的业务需求来灵活控制事务的行为。

声明式事务注解方式

Spring声明式事务也可以通过注解的方式来实现。具体来说,可以在需要使用事务的方法上添加@Transactional注解,并通过该注解的属性来指定事务的传播机制、隔离级别、超时时间等信息。

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 3600)
public void transferMoney(Account fromAccount, Account toAccount, double amount) {
    fromAccount.withdraw(amount);
    toAccount.deposit(amount);
}

在上面的代码中,通过@Transactional注解来声明了事务的传播机制为Propagation.REQUIRED,隔离级别为Isolation.DEFAULT,超时时间为3600秒。在方法执行时,Spring会根据注解中的信息自动管理事务的行为。

注解式声明事务的优点是代码简洁、可读性好,灵活性和可用性高,容易维护和调试。但是它也有一些缺点,例如注解的使用可能会导致代码分散,而且无法通过配置文件来管理事务,而且可能会引入一些意想不到的问题。

@Transactional注解的常用参数包括:

除了上述常用参数外,@Transactional注解还有其他一些参数,例如transactionManagerrollbackForClassNamenoRollbackForClassNamevalue等,具体用法可以参考Spring官方文档。

在使用@Transactional注解时,需要根据具体的业务需求来选择合适的参数,以保证事务的正确性和可靠性。

事务注解失效情况

Spring的声明式事务注解可能失效的情况包括:

如果遇到声明式事务注解失效的情况,需要检查上述问题并进行相应的修复。

代码规范中强调

@Transactional事务不要滥用。事务会影响数据库的QPS,另外使用事务的敌方需要考虑各方面的回滚方案,包括缓存回滚、搜索引擎、消息补偿、统计修正等。

在使用Spring事务时,需要注意对于事务的传播机制和隔离级别的设置,以及对于事务的异常处理等问题。正确地使用Spring事务可以提高系统的数据一致性和可靠性。

什么是Spring事务传播机制

Spring事务传播机制是指在多个事务操作发生时,如何管理这些操作之间的事务关系。Spring事务传播机制可以通过Propagation枚举类中的不同值来指定,共包括七种不同的传播行为。具体来说,Spring事务传播机制包括以下七种:

在使用Spring事务传播机制时,需要根据具体的业务需求来选择合适的传播行为,以保证事务的正确性和可靠性。同时,需要注意事务的异常处理等问题,以避免数据不一致或丢失的情况发生。

@Transactional注解中的传播机制

除了在代码中使用编程式事务和声明式事务外,Spring还提供了@Transactional注解来实现事务控制。在使用@Transactional注解时,可以通过propagation属性来指定事务的传播机制,例如:

@Transactional(propagation = Propagation.REQUIRED)
public void transferMoney(Account fromAccount, Account toAccount, double amount) {
    fromAccount.withdraw(amount);
    toAccount.deposit(amount);
}

在上面的代码中,通过propagation属性来指定了事务的传播机制为Propagation.REQUIRED,即如果当前没有事务,则创建一个新的事务;如果当前已经存在事务,则加入该事务。

除了Propagation枚举类中的七种传播行为外,@Transactional注解还可以通过isolationtimeoutreadOnly等属性来指定事务的隔离级别、超时时间和只读事务等信息。

在使用@Transactional注解时,需要根据具体的业务需求来选择合适的传播行为和其他属性,以保证事务的正确性和可靠性。

Spring事务的隔离级别

Spring事务的隔离级别是指多个事务之间的隔离程度,它可以通过设置isolation属性来指定。Spring事务的隔离级别包括以下五种:

在选择隔离级别时,需要根据具体的业务需求来选择合适的级别。一般来说,如果不需要在事务中读取未提交的数据,那么可以选择READ_COMMITTED级别;如果需要避免“不可重复读”问题,可以选择REPEATABLE_READ级别;如果需要避免“幻读”问题,可以选择SERIALIZABLE级别。但是需要注意的是,隔离级别越高,事务的并发性越差,因此需要根据具体业务场景来权衡隔离级别和性能。

不可重复读和幻读的区别

不可重复读和幻读都是在并发读写数据时可能出现的问题。

不可重复读指的是在一个事务中多次读取同一数据,但是由于其他事务的修改,导致两次读取的结果不一致。例如,事务A在读取某个数据时,事务B修改了该数据并提交,然后事务A再次读取该数据时,得到了不同的结果。

幻读是指在一个事务中多次读取同一范围内的数据,但是由于其他事务的插入操作,导致两次读取的结果不一致。例如,事务A在读取某个范围内的数据时,事务B插入了一条数据并提交,然后事务A再次读取该范围内的数据时,得到了不同的结果。

不可重复读和幻读的区别在于,不可重复读是在读取同一数据时出现问题,而幻读是在读取同一范围内的数据时出现问题。解决不可重复读的问题可以使用锁机制或者提高事务的隔离级别,而解决幻读的问题可以使用锁机制或者使用更高的隔离级别,例如SERIALIZABLE级别。

rollbackFor属性

在使用@Transactional注解进行声明式事务管理时,可以通过rollbackFor属性来指定哪些异常类型需要回滚事务。需要注意的是,rollbackFor属性指定的异常类型必须是Throwable类型或其子类,并且必须包含在Spring事务抛出的异常类型之内。如果指定的异常类型不正确或不在事务回滚的异常类型之内,可能会导致事务无法正确回滚或者回滚不完整的问题。

如果需要指定多个异常类型,可以使用数组的方式进行指定,例如:

@Transactional(rollbackFor = {SQLException.class, IOException.class})
public void doSomething() {
    // ...
}

在上面的代码中,指定了SQLExceptionIOException两种异常类型需要回滚事务。默认情况只有RuntimeException和Error会触发事务回滚。

除了rollbackFor属性外,@Transactional注解还有其他一些属性可以用于指定事务的属性和行为,包括propagationisolationtimeoutreadOnly等。需要根据具体的业务需求来选择合适的属性和行为,以保证事务的正确性和可靠性。

到此这篇关于一文搞清楚Spring事务的文章就介绍到这了,更多相关Java Spring事务内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯