事务七种传播特性

目录

什么是事务

REQUIRED:

SUPPORTS:

 MANDATORY:

 REQUIRES_NEW:

NOT_SUPPORTED:

NEVER:

 NESTED:

小结:


@Transactional(propagation = Propagation.REQUIRED)

什么是事务

事务就是多个操作简称,要么全部执行成功,要么没有执行(执行不生效)

try{
 
    Connection conn = getConnection();
 
    // 执行一些数据库操作
 
}catch(Exception e){
 
       conn.rollback();
 
}finally{
 
    conn.close();
 
}

 

REQUIRED:

  • 如果当前存在事务,则加入该事务。如果没有事务,则新建一个事务。

  • 这是最常用的传播行为,默认值为REQUIRED。

@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    @Transactional
    public void updateProductPrice(Long productId, double newPrice) {
        // 在此方法中,会开启一个新的事务

        Product product = productRepository.findById(productId).orElse(null);
        if (product != null) {
            product.setPrice(newPrice);
            productRepository.save(product);
        }
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void adjustStock(Long productId, int quantity) {
        // 这个方法将会以一个新的事务运行

        Product product = productRepository.findById(productId).orElse(null);
        if (product != null) {
            int newStock = product.getStock() + quantity;
            product.setStock(newStock);
            productRepository.save(product);
        }
    }
}
  1. updateProductPrice方法标记了@Transactional注解,它使用默认的传播行为Propagation.REQUIRED,这意味着如果当前已经存在一个事务,该方法将会加入到这个事务中;如果没有事务,则会开启一个新的事务。

  2. adjustStock方法标记了@Transactional(propagation = Propagation.REQUIRES_NEW),这表示在调用该方法时,将会开启一个新的事务,不论外部是否存在事务。


SUPPORTS:

表示如果当前存在事务,则加入该事务;如果不存在事务,则不使用事务。

@Service
public class OrderService {

    @Autowired
    private OrderRepository orderRepository;

    @Transactional(propagation = Propagation.SUPPORTS)
    public void updateOrderStatus(Long orderId, String newStatus) {
        // 如果存在事务,则加入该事务;如果不存在事务,则以非事务方式执行

        Order order = orderRepository.findById(orderId);
        order.setStatus(newStatus);
        orderRepository.save(order);
    }
}

 
MANDATORY:

表示方法必须在事务中被调用,如果当前没有事务,就抛出异常。

@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    @Transactional(propagation = Propagation.NEVER)
    public void updateProductPrice(Long productId, double newPrice) {
        // 在此方法中,不应该在事务中执行

        Product product = productRepository.findById(productId);
        product.setPrice(newPrice);
        productRepository.save(product);
    }

}

 
REQUIRES_NEW:

  • 总是开启一个新的事务。如果当前存在事务,则将当前事务挂起。
  • 这种传播行为会导致当前事务被挂起,新事务执行完毕后,再恢复之前的事务。
    @Service
    public class OrderService {
    
        @Autowired
        private OrderRepository orderRepository;
    
        @Transactional
        public void createOrder(Order order) {
            // 在此方法中,会开启一个新的事务
    
            orderRepository.save(order);
            
            try {
                updateInventory(order); // 调用一个更新库存的方法
            } catch (Exception e) {
                // 处理异常
            }
        }
    
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public void updateInventory(Order order) {
            // 这个方法将会以一个新的事务运行
    
            // 假设这里有更新库存的逻辑
            // 如果更新库存过程中出现异常,该事务会独立于createOrder方法的事务并被回滚
        }
    }
    

 

NOT_SUPPORTED:

  • 如果当前存在事务,则该方法将在没有事务的环境中执行。
  • 如果当前不存在事务,则该方法将在没有事务的环境中执行。
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional(propagation = Propagation.REQUIRED)
    public void updateUser() {
        // 在这个方法内部会开启一个事务

        // 调用updateUserDetails方法
        updateUserDetails();

        // 手动抛出异常,模拟事务回滚
        throw new RuntimeException("Simulating an error");
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void updateUserDetails() {
        // 这个方法不会参与到外部事务中,会在没有事务的环境中执行
        User user = userRepository.findById(1L).orElse(null);
        if (user != null) {
            user.setName("New Name");
            userRepository.save(user);
        }
    }
}
  • updateUser方法表示会开启一个事务,而updateUserDetails方法表示不参与外部事务。
  • 当updateUser方法被调用时,它会内部调用updateUserDetails方法。在updateUserDetails方法内部进行的数据库操作不会受updateUser方法的事务控制,而是在没有事务的环境中执行。


NEVER:

以非事务方式执行,如果当前存在事务,则抛出异常。

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional(propagation = Propagation.NEVER)
    public void createUser(User user) {
        // 在此方法中,不应该在事务中执行

        userRepository.save(user);
    }

}

 
NESTED:

支持当前事务,如果当前事务存在,则执行一个嵌套事务(嵌套的事务可以独立于当前事务进行单独地提交或回滚),如果当前没有事务,就新建一个事务。 

小结:

REQUIRED:

如果当前存在事务,则加入该事务。如果没有事务,则新建一个事务。

这是最常用的传播行为,默认值为REQUIRED。

SUPPORTS:

表示如果当前存在事务,则加入该事务;如果不存在事务,则不使用事务。

MANDATORY:

表示方法必须在事务中被调用,如果当前没有事务,就抛出异常。

REQUIRES_NEW:

总是开启一个新的事务。如果当前存在事务,则将当前事务挂起。

这种传播行为会导致当前事务被挂起,新事务执行完毕后,再恢复之前的事务。

NOT_SUPPORTED:

如果当前存在事务,则该方法将在没有事务的环境中执行。

如果当前不存在事务,则该方法将在没有事务的环境中执行。

NEVER:

以非事务方式执行,如果当前存在事务,则抛出异常。

NESTED:

支持当前事务,如果当前事务存在,则执行一个嵌套事务(嵌套的事务可以独立于当前事务进行单独地提交或回滚),如果当前没有事务,就新建一个事务。 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值