26.事务的安全性与日志的添加

我有一个商品除了基本参数描述还有一个详细的商品描述,此时我会建立两个表实现存储最优化。

1.那么再插入数据的时候就要同时向两张表插入数据,如果一个表数据插入失败那么另一张表也要插入失败。让两者的状态保持一致,这就涉及到事务的安全性问题。

2.向数据库中插入的数据,如果某字段的数据前端不需要前端传递,那么就需要在后台进行设置,比如状态state,就需要在后台进行设置,也就是初始数据

3.还有在插入数据的时候,id是后台自动生成的,如果前台传递过来的id数据,那么这时不正常的。需要把id强制为空。


a)在itemService中新增一个saveItem方法,在调用BaseService中的save方法保存商品基本属性之后(因为商品的ID是后台自动创建的)去调用itemDescService中的save方法保存商品描述信息。以前都是在controller文件注入service,但现在在service里面也注入了事务,那么此时是一个事务还是两个事务?

答:是一个事务,这属于事务的传递,可以看日志信息证明这一点。

b).除了事务问题,还有状态是前台未提供的数据需要后台添加,比如state

c).item是controller根据用户提交的数据来创建的,id也是由后台自动创建的。如果用户在前端提交了id过来就有问题了。所以要强制id为空,也就是无论前端是否有id,我都设置为null,考虑到一个安全性的问题。




注意:service中切记不能用try--catch。如果做了try--catch,那么异常不会抛出,事务就不会回滚。尤其是涉及到事务的时候。


当产品在生成环境中运行时,如果一段代码出现问题,那怎么去确定问题所在呢?

所以日志就解决上述问题,显得尤为重要。

重点:添加日志。



package com.taotao.manager.controller;

import java.util.List;

import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.github.pagehelper.PageInfo;
import com.taotao.common.bean.EasyUIResult;
import com.taotao.manager.pojo.Item;
import com.taotao.manager.pojo.ItemParamItem;
import com.taotao.manager.service.ItemService;

@RequestMapping("item")
@Controller
public class ItemController {
    
    private static final Logger LOGGER=org.slf4j.LoggerFactory.getLogger(ItemController.class);
    @Autowired
    private ItemService itemService;
    /**
     * 增加商品和商品描述
     * @param item
     * @param desc
     * @return
     */
    @RequestMapping(method=RequestMethod.POST)
    public ResponseEntity<Void> saveItem(Item item,@RequestParam("desc") String desc,@RequestParam("itemParams") String itemParams){
        try {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("新增商品!item={},desc={}",item,desc);
            }
            
            this.itemService.saveItem(item, desc,itemParams);
            
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("新增商品成功!ItemId="+item.getId());
            }
            
//            201
            return ResponseEntity.status(HttpStatus.CREATED).build();
        } catch (Exception e) {
          LOGGER.error("新增商品出错!item="+item,e);
        }
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        
    }
}


在上面代码添加LOGGER.isDebugEnabled()判断的原因是:比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来,也是说大于等于的级别的日志才输出。

以上考虑全面你就算是中级开发工程师了。

如果写成以下这种



1.想到LOGGER.error()语句的是初级开发工程师

2.想到LOGGER.debug()语句的是中级开发工程师

3.上面的代码还是存在问题的:现在是debugger输出,如果现在把日志的级别调成INFO会输出吗?不会输出,但是LOGGER.debug()语句还是会执行。执行但是不输出就会有些浪费,就会影响性能。所以要加判断,判断你是否启用debugger模式。如果启用了再执行LOGGER.debug()语句输出。以下代码就非常完美了。



这个判断很关键,可能直接影响整个系统的性能。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值