事务管理-cnblog

4). DishServiceImpl中实现方法saveWithFlavor

页面传递的菜品口味信息,仅仅包含name 和 value属性,缺少一个非常重要的属性dishId, 所以在保存完菜品的基本信息后,我们需要获取到菜品ID,然后为菜品口味对象属性dishId赋值。

具体逻辑如下:

①. 保存菜品基本信息 ;

②. 获取保存的菜品ID ;

③. 获取菜品口味列表,遍历列表,为菜品口味对象属性dishId赋值;

④. 批量保存菜品口味列表;

代码实现如下:

@Autowired
private DishFlavorService dishFlavorService;
/**
* 新增菜品,同时保存对应的口味数据
* @param dishDto
*/
@Transactional
public void saveWithFlavor(DishDto dishDto) {
    //保存菜品的基本信息到菜品表dish
    this.save(dishDto);
	
    Long dishId = dishDto.getId();//菜品id
    //菜品口味
    List<DishFlavor> flavors = dishDto.getFlavors();
    flavors = flavors.stream().map((item) -> {
        item.setDishId(dishId);
        return item;
    }).collect(Collectors.toList());

    //保存菜品口味数据到菜品口味表dish_flavor
    dishFlavorService.saveBatch(flavors);
}

说明:

​ 由于在 saveWithFlavor 方法中,进行了两次数据库的保存操作,操作了两张表,那么为了保证数据的一致性,我们需要在方法上加上注解 @Transactional来控制事务。

5). 在引导类上加注解 @EnableTransactionManagement

Service层方法上加的注解@Transactional要想生效,需要在引导类上加上注解 @EnableTransactionManagement, 开启对事务的支持。

@Slf4j
@SpringBootApplication
@ServletComponentScan
@EnableTransactionManagement //开启对事物管理的支持
public class ReggieApplication {
    public static void main(String[] args) {
        SpringApplication.run(ReggieApplication.class,args);
        log.info("项目启动成功...");
    }
}

事务管理与乐观锁冲突解决方案

  • 避免同时出现事务管理和乐观锁
  • 出现后如何解决
    • 如对一张表进行(重复的update语句),version字段会加1
      • 开启事务管理,会把这些update语句同时成功,同时失败
        • 而这里会被认为是并发操作,乐观锁生效
        • 第二次update,version不匹配
        • 所有我们在业务代码中人工将version字段+1
@Override
    @Transactional
    public void modifyDefaultAddress(Long id) {
        // 判断id的合法性
        AddressBook address = addressBookService.getById(id);
        if(address==null){
            throw new BusinessException(ErrorResult.addressFormError());
        }

        // 将当前用户的所有的收货地址is_default 设为0
        Long userId = BaseContext.getUserId();
        List<AddressBook> addressBooks = this.allAddress();

        addressBooks.forEach(item->{
            item.setIsDefault(0);
        });

        // 这里进行二次更新语句需要进行事务处理

        addressBookService.updateBatchById(addressBooks);
        // 将当前id对应的收货地址设置为1
//        AddressBook addressBook = new AddressBook();
//        addressBook.setId(id);
//        addressBook.setIsDefault(1);

        // 开启了事务管理,有开启的乐观锁,这里需要获取修改后的version
//        addressBooks.forEach(item->{
//            if(item.getId()==id){
//                address.setVersion(item.getVersion());
//            }
//        });
        address.setIsDefault(1);
        address.setVersion(address.getVersion()+1);
//        address.setDescription("test1");
        addressBookService.updateById(address);

//        LambdaQueryWrapper<AddressBook> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq()
//        List<AddressBookVo> addressBookVos = this.allAddress();

    }
posted @ 2023-02-04 16:54  凌歆  阅读(91)  评论(0)    收藏  举报