当前位置: 首页 > wzjs >正文

贵阳城乡建设学校网站北京seo优化推广

贵阳城乡建设学校网站,北京seo优化推广,网页设计与制作教程期末考试试题,中国做投资的网站引言 在 Spring Boot 中,事务管理是一个非常重要的功能,尤其是在涉及数据库操作的业务场景中。Spring 提供了强大的事务管理支持,能够帮助我们简化事务的管理和控制。本文将详细介绍 Spring Boot 中事务的用法,包括事务的基本概…

引言 

在 Spring Boot 中,事务管理是一个非常重要的功能,尤其是在涉及数据库操作的业务场景中。Spring 提供了强大的事务管理支持,能够帮助我们简化事务的管理和控制。本文将详细介绍 Spring Boot 中事务的用法,包括事务的基本概念、事务的配置、事务的传播行为、事务的隔离级别以及事务的回滚机制。

1. 事务的基本概念

事务(Transaction)是指一组数据库操作,这些操作要么全部成功,要么全部失败。事务的四大特性(ACID)包括:

  • 原子性(Atomicity):事务中的所有操作要么全部成功,要么全部失败。

  • 一致性(Consistency):事务执行前后,数据库的状态保持一致。

  • 隔离性(Isolation):多个事务并发执行时,彼此之间互不干扰。

  • 持久性(Durability):事务一旦提交,对数据库的修改是永久性的。

在 Spring Boot 中,事务管理是通过 @Transactional 注解来实现的。

2. Spring Boot 中事务的配置

2.1 启用事务管理

Spring Boot 默认已经集成了事务管理功能,只需要在配置类或启动类上添加 @EnableTransactionManagement 注解即可启用事务管理。

@SpringBootApplication
@EnableTransactionManagement // 启用事务管理
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

2.2 配置数据源和事务管理器

Spring Boot 默认使用 DataSourceTransactionManager 作为事务管理器。如果你使用的是 Spring Data JPA,事务管理器会自动配置。

# application.yml
spring:datasource:url: jdbc:mysql://localhost:3306/mydbusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver

3. 使用 @Transactional 注解

@Transactional 是 Spring 提供的事务管理注解,可以标注在类或方法上。标注在类上时,表示该类中的所有方法都启用事务管理;标注在方法上时,表示该方法启用事务管理。

@Service
public class UserService {@Autowiredprivate UserRepository userRepository;@Transactional // 开启事务  表示该方法开启了事务public void createUser(User user) {userRepository.save(user);}
}

3.2 事务的传播行为

事务的传播行为(Propagation)定义了事务方法之间的调用关系。Spring 提供了以下几种传播行为:

  • REQUIRED(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。(适用于大多数业务场景,尤其是需要保证多个操作在同一个事务中执行的场景。 例如,订单创建时需要同时更新订单表和库存表。)

  • REQUIRES_NEW:无论当前是否存在事务,都创建一个新的事务。(适用于需要独立事务的场景,尤其是日志记录、审计等操作。 例如,记录操作日志时,即使主事务失败,日志记录仍然需要成功。)

  • SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。(适用于不需要强制事务的场景,例如查询操作。 例如,查询用户信息时,如果调用方有事务,则加入事务;如果没有事务,则以非事务方式执行。)

  • NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则挂起该事务。(适用于不需要事务支持的场景,例如发送消息、调用外部接口等。 例如,发送短信通知时,不需要事务支持。)

  • MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(适用于强制要求调用方必须有事务的场景。 例如,某些核心业务逻辑必须在一个事务中执行。)

  • NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。(适用于强制要求调用方不能有事务的场景。 例如,某些只读操作或外部调用。)

  • NESTED:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则创建一个新的事务。(适用于需要部分回滚的场景。 例如,订单创建时需要更新多个表,如果某个表更新失败,只需要回滚该表的操作,而不影响其他表的操作。)

  • 示例:

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateUser(User user) {userRepository.save(user);
    }

    3.3 事务的隔离级别

    事务的隔离级别(Isolation)定义了事务之间的可见性。Spring 支持以下几种隔离级别:

  • DEFAULT:使用数据库的默认隔离级别。(适用于大多数通用场景,尤其是当你对数据库的默认行为没有特殊要求时。 如果你不确定应该选择哪种隔离级别,可以使用 DEFAULT,让数据库根据其默认行为处理事务。)

  • READ_UNCOMMITTED:允许读取未提交的数据变更,可能会导致脏读、幻读和不可重复读。(适用于对数据一致性要求不高的场景,例如统计数据的读取或日志记录。 不适用于涉及资金、订单等对数据一致性要求高的场景。)

  • READ_COMMITTED:只能读取已提交的数据,可以避免脏读,但可能会导致幻读和不可重复读。(适用于大多数业务场景,尤其是对数据一致性有一定要求但不需要严格隔离的场景。 例如,电商系统中的订单查询、用户信息查询等。)

  • REPEATABLE_READ:确保在同一事务中多次读取同一数据时结果一致,可以避免脏读和不可重复读,但可能会导致幻读。(适用于对数据一致性要求较高的场景,例如银行系统中的账户余额查询。 例如,在一个事务中多次读取同一账户的余额时,确保结果一致。)

  • SERIALIZABLE:最高隔离级别,确保事务串行执行,可以避免脏读、幻读和不可重复读(适用于对数据一致性要求极高的场景,例如金融系统中的资金清算、库存管理等。 由于性能开销较大,通常只在必要时使用。)

  • 示例:

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public User getUserById(Long id) {return userRepository.findById(id).orElse(null);
    }

    3.4 事务的回滚机制

    默认情况下,Spring 会在方法抛出 RuntimeException 或 Error 时回滚事务。如果需要自定义回滚规则,可以通过 rollbackFor(哪些异常回滚) 和 noRollbackFor(哪些异常不会回滚) 属性来指定。

    示例:

    @Transactional(rollbackFor = Exception.class) // 所有异常都回滚
    public void updateUser(User user) throws Exception {userRepository.save(user);if (user.getName() == null) {throw new Exception("用户名不能为空"); // 抛出受检异常}
    }

    4. 事务的嵌套与传播行为

    在复杂的业务场景中,可能会存在事务方法调用事务方法的情况。此时,事务的传播行为决定了事务的嵌套方式。

  • 4.1 嵌套事务示例

    @Service
    public class OrderService {@Autowiredprivate UserService userService;@Transactional  //一级事务public void createOrder(Order order) {// 保存订单orderRepository.save(order);// 调用另一个事务方法userService.updateUser(order.getUser());}
    }@Service
    public class UserService {@Transactional(propagation = Propagation.REQUIRES_NEW) //二级事务public void updateUser(User user) {userRepository.save(user);}
    }

    在上面的示例中,createOrder 方法调用 updateUser 方法时,updateUser 方法会开启一个新的事务。

5. 事务的注意事项(事务不生效的几种情况)

  1. 事务方法的可见性

    • @Transactional 只能应用于 public 方法。如果应用于 private 或 protected 方法,事务将不会生效。Spring 的事务管理是基于代理模式实现的,代理对象只能拦截 public 方法。对于 private 或 protected 方法,Spring 无法生成代理,因此事务不会生效。

      @Service
      public class UserService {@Autowiredprivate UserRepository userRepository;// 正确:public 方法,事务生效@Transactionalpublic void createUser(User user) {userRepository.save(user);}// 错误:private 方法,事务不会生效@Transactionalprivate void updateUser(User user) {userRepository.save(user);}// 错误:protected 方法,事务不会生效@Transactionalprotected void deleteUser(Long userId) {userRepository.deleteById(userId);}
      }

  2. 事务的自我调用问题

    • 如果事务方法调用了同一个类中的另一个事务方法,事务的传播行为可能不会生效。这是因为Spring 的代理对象只能拦截从外部调用的方法。如果事务方法在同一个类中调用另一个事务方法,实际上是直接调用目标方法,而不是通过代理对象调用,因此事务的传播行为不会生效。

      @Service
      public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Transactionalpublic void createOrder(Order order) {// 保存订单orderRepository.save(order);// 调用另一个事务方法(自我调用)updateInventory(order.getProductId(), order.getQuantity());}@Transactional(propagation = Propagation.REQUIRES_NEW)public void updateInventory(Long productId, int quantity) {// 更新库存逻辑}
      }

      在上面的示例中,createOrder 方法调用了 updateInventory 方法,但由于是自我调用,updateInventory 方法的事务传播行为(REQUIRES_NEW)不会生效。

    • 解决方法:

    • 将事务方法拆分到不同的类中
      将 updateInventory 方法移到另一个服务类中,通过依赖注入调用。

      @Service
      public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate InventoryService inventoryService;@Transactionalpublic void createOrder(Order order) {// 保存订单orderRepository.save(order);// 调用另一个服务类的事务方法inventoryService.updateInventory(order.getProductId(), order.getQuantity());}
      }@Service
      public class InventoryService {@Transactional(propagation = Propagation.REQUIRES_NEW)public void updateInventory(Long productId, int quantity) {// 更新库存逻辑}
      }

  3. 事务的超时设置

    • 可以通过 @Transactional(timeout = 10) 设置事务的超时时间(单位为秒)。如果事务执行时间超过指定时间,事务将自动回滚。

      @Service
      public class ReportService {@Autowiredprivate ReportRepository reportRepository;@Transactional(timeout = 10) // 设置事务超时时间为 10 秒public void generateReport() {// 模拟耗时操作for (int i = 0; i < 1000000; i++) {reportRepository.save(new Report("Report " + i));}}
      }

      在上面的示例中,如果 generateReport 方法的执行时间超过 10 秒,事务将自动回滚。

 

6. 总结

Spring Boot 提供了强大的事务管理功能,通过 @Transactional 注解可以轻松实现事务的控制。在实际开发中,需要根据业务需求选择合适的传播行为和隔离级别,同时注意事务方法的可见性和自我调用问题。

通过本文的介绍,相信你已经掌握了 Spring Boot 中事务的基本用法。如果你有更多问题,欢迎在评论区留言讨论!

http://www.dtcms.com/wzjs/235370.html

相关文章:

  • 怎么把asp网站改成php淘宝店铺推广方式有哪些
  • 什么叫商业网站网站的建设流程
  • 构建动态网站设计宁波seo公司排名榜
  • 怎样发布信息到网上温州seo优化
  • 上海免费推广网站有哪些今天重要新闻
  • 安卓编程入门自学谷歌seo网站运营
  • 有没有个人网站珠海百度推广优化排名
  • 潍坊市建设一体化平台网站刷排名seo
  • 深圳龙岗网站建设公司网站关键词公司
  • 做数独的网站bt磁力种子搜索引擎
  • 衡水做网站技术注册推广
  • 做靓号网站百度云
  • 网站做数据分析的意义百度搜索风云榜电视剧
  • 网站建设的参考书籍今日头条(官方版本)
  • 大学网站建设方案伊春seo
  • 外贸做的亚马逊网站是哪个江苏企业网站建设
  • 网站开发常遇到客户问题网络营销推广方案
  • 深圳哪里可以做物流网站成品网站1688入口网页版怎样
  • 网站接单做项目百度小程序怎么进入
  • 工程公司起名大全字库网络推广优化平台
  • 长安做网站百度官网认证入口
  • 做茶歇的网站百度指数数据分析平台官网
  • 淘宝网站建设杭州seo技术优化技巧
  • 义乌市网站制作现在的seo1发布页在哪里
  • 做ui的网站官方百度下载安装
  • 框架网站建设网站制作报价表
  • linux做网站服务器吗莆田seo推广公司
  • 怎么建网站 手机版爱站长工具
  • 旅游网站源代码模板网络营销推广技巧
  • 网站建设开发综合实训小结网络软文营销的案例