目录
@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);
}
}
}
updateProductPrice方法标记了@Transactional注解,它使用默认的传播行为Propagation.REQUIRED,这意味着如果当前已经存在一个事务,该方法将会加入到这个事务中;如果没有事务,则会开启一个新的事务。
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:
支持当前事务,如果当前事务存在,则执行一个嵌套事务(嵌套的事务可以独立于当前事务进行单独地提交或回滚),如果当前没有事务,就新建一个事务。