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

来源:互联网 发布:zwift 软件下载 编辑:程序博客网 时间:2024/06/07 07:23

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

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")@Controllerpublic 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()语句输出。以下代码就非常完美了。



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



原创粉丝点击