什么情况下用到事务

本文详细介绍了事务的概念及其在并发操作中的作用,强调了事务的四大特性:原子性、一致性、隔离性和持久性。并讨论了在软件开发过程中如何通过配置切面来实现事务控制。

事务一般用在并发操作多张表的时候使用,用于保护用户数据的完整性。

或者说,事务是在对数据进行操作,并且确定两种操作同时成立时运用,这样做的目的就是保证两个操作都正确,都达到目的,只要一方出错,就会回滚数据,保证了两个操作的安全。

在开发中,一般情况下都会配置切面,进行事务的控制。

什么是事务:

事务是访问或更改数据库的一个程序执行单元。

事务具有4个属性:原子性,一致性,隔离性,持久性。

原子性:事务是一个不可分割的操作单位,事务中的所有操作要么全部成功,要么全部失败。

一致性:一致性和原子性密切相关。

隔离性:并发执行多个不同的事务之间是互不干扰的。

持久性:事务一旦提交,对数据库操作的影响是具有持久性的。

 

转载于:https://my.oschina.net/luleilei516/blog/843125

### ### 事务管理的适用业务场景 Spring事务管理适用于多种业务场景,尤其是在需要保证数据一致性和完整性的关键操作中。以下是一些典型的应用场景: #### 核心业务操作 在金融、电商、ERP等系统中,核心业务操作通常需要多个数据库操作协同完成,例如订单创建、支付处理、库存更新等。这些操作必须全部成功或全部失败,以保证数据一致性。例如: ```java @Transactional public void placeOrder(Order order) { orderRepository.save(order); inventoryService.reduceStock(order.getProductId(), order.getQuantity()); } ``` 上述代码中,`placeOrder`方法将订单保存与库存减少作为一个事务执行,确保两者要么都成功,要么都失败[^1]。 #### 多表操作 在数据管理系统中,一个业务操作可能涉及多个表的更新,如用户注册时需要同时更新用户表和日志表。使用事务可以确保这些操作要么全部完成,要么全部不执行: ```java @Transactional public void registerUser(User user) { userRepository.save(user); logRepository.save(new RegistrationLog(user.getId(), LocalDateTime.now())); } ``` 此方法确保用户注册和日志记录在同一个事务中完成,避免数据不一致的问题。 #### 事务传播行为的应用 在复杂的业务逻辑中,事务方法可能被其他事务方法调用,此时事务传播机制决定了事务的边界。例如,在订单处理中,`placeOrder`方法调用`processPayment`方法,两者都使用事务管理: ```java @Transactional(propagation = Propagation.REQUIRED) public void placeOrder(Order order) { orderRepository.save(order); paymentService.processPayment(order.getPayment()); } @Transactional(propagation = Propagation.REQUIRES_NEW) public void processPayment(Payment payment) { paymentRepository.save(payment); } ``` `placeOrder`方法使用`REQUIRED`传播行为,表示如果当前存在事务,则加入该事务;而`processPayment`方法使用`REQUIRES_NEW`,表示每次调用时都新建一个事务,确保支付操作独立提交或回滚[^1]。 #### 日志记录与事务分离 在某些系统中,如审计日志记录,日志写入操作可能需要与业务事务分离,以避免日志失败影响主业务流程。此时可以使用`NOT_SUPPORTED`传播行为,使日志操作不参与事务: ```java @Transactional(propagation = Propagation.NOT_SUPPORTED) public void logOperation(String message) { logRepository.save(new AuditLog(message)); } ``` 这种方式确保日志操作不会影响主事务的提交或回滚,适用于非关键操作的记录[^3]。 #### 事务回滚与异常处理 在业务逻辑中,某些异常可能需要触发事务回滚,例如业务规则校验失败或外部服务调用失败。Spring允许通过`rollbackFor`属性指定回滚规则: ```java @Transactional(rollbackFor = InsufficientStockException.class) public void reduceStock(Long productId, int quantity) throws InsufficientStockException { Product product = productRepository.findById(productId); if (product.getStock() < quantity) { throw new InsufficientStockException("库存不足"); } product.setStock(product.getStock() - quantity); productRepository.save(product); } ``` 此方法在库存不足时抛出异常并触发事务回滚,确保数据一致性。 #### 自调用事务失效的处理 在实际开发中,自调用(self-invocation)可能导致事务失效,例如一个类中的非事务方法直接调用事务方法: ```java public void processOrder() { createOrder(); // 直接调用事务方法 → 失效 } @Transactional public void createOrder() { // 业务逻辑 } ``` 由于Spring事务基于代理实现,自调用会绕过代理,导致事务失效。解决方法是将事务方法提取到另一个类中,或通过`AopContext.currentProxy()`显式调用代理对象[^2]。 #### 嵌套事务的应用 在某些复杂的业务流程中,嵌套事务可以提供更细粒度的事务控制。例如,在订单处理过程中,如果支付失败,可以仅回滚支付部分而不影响订单创建: ```java @Transactional(propagation = Propagation.NESTED) public void processPayment(Payment payment) { paymentRepository.save(payment); } ``` 嵌套事务允许在父事务中创建子事务,子事务可以独立提交或回滚,适用于需要部分回滚的场景[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值