MyBatis一级缓存引发的问题
本文由发表于1年前 | 数据库 | 评论数 1 |  被围观 1,936 views+

一般的,我们在写一个系统的时候,都会分为持久层,服务层,和控制层,各层之间职责分明,对应的Entity,DTO,VO也是很明确知道用在哪里的,但是有时候为了方便,特别是用MyBatis的时候,直接从持久层返回一个vo,然后这个vo又作为方法的参数在系统之间来回调用,那么会引发什么样的问题呢?

假设我们有如下代码:


/**
 * 确认订单
 */
public boolean confirmOrder(String orderId){
    OrderVo orderVo = orderDao.findByOrderId(orderId);
    // 假设计算订单号需要用到一个特殊的利率
    BigDecimal annualRate = new BigDecimal(0.12);
    // 根据订单号和利率计算实际的价格
    String realAmount = calculateRealAmount(orderId, annualRate);
    System.out.println(orderVo.getAnnualRate.longValue());
}

/**
 * 计算订单实际价格的方法,传入orderVo和实际的利率,用于计算订单价格
 */
private BigDecimal calculateRealAmount(OrderVo orderVo, BigDecimal annualRate){
    OrderVo orderVo = orderDao.findByOrderId(orderId);
    orderVo.setAnnualRate(annualRate);  // 设置新的计算利率
    calculateRealAmount(orderVo);
}

/**
 * 计算订单实际价格的方法,传入orderVo用于计算
 */
private BigDecimal calculateRealAmount(OrderVo orderVo){
    return NumberUtils.mulBigDecimal(orderVo.getAmount, orderVo.getAnnualRate);
}

假设confirmOrder()是处于一个事务里面,confirmOrder()方法里面通过calculateRealAmount()方法计算了实际的订单金额,这两个方法都通过orderDao.findByOrderId(orderId);查找到了OrderVo,由于MyBatis默认开启了以及缓存,实际上这两个方法查找出来的是同一个OrderVo对象,所以calculateRealAmount()里面对orderVo的改动,也会影响到confirmOrder()里面的vo,所以confirmOrder(String orderId)最后一行输出的值也不是刚查找出来的了,使用不当,会造成潜在的bug。

下面就来总结一下这个问题。

代码规范问题引发脏数据

原因是MyBatis xml文件里面读取出来的是一个VO,某一些方法也使用该VO作为参数,在传递VO参数的时候,对VO进行了重新设置,导致接下来的地方读取vo的属性读到了脏数据。

项目规范:

分清各层数据的职责,防止出现类似情况;
Entity查找出来不要更改,更改后则一定要入库处理,也不要作为方法的参数进行传递;
禁止从数据库里面直接查找出VO。

mybatis一级缓存(session cache)引发的问题

【mybatis】多次查询缓存的问题

深入理解mybatis原理

除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。
本文链接:http://www.itzhai.com/mybatis-first-level-cache-repeatable-read-problem.html
关键字: , ,
arthinking Java技术交流群:280755654,入门群:428693174 more
分享到:
 
2016 6/16
文章评论
    一条评论
  1. maijunjin 2016年11月16日10:38:36  #-49楼 回复 回复

    还有一层就是如果可以不要去修改任意的对象,宁愿new一个新的

给我留言

有人回复时邮件通知我
数据库的相关文章
随机文章 本月热门 热评
1 Java基础笔记 – 线程同步问题 解决同步问题的方法 synchronized方法 同步代码块 2011/10/24
2 Java笔记 – 泛型 泛型方法 泛型接口 擦除 边界 通配符(1) 2014/3/16
3 Java基础笔记 – 通过反射机制动态创建和访问数组 2011/10/8
4 YUI介绍以及快速入门 Yahoo的JS框架 2011/12/19
5 Java笔记 – 正则表达式 matches()与lookingAt() 2013/12/15
6 UML笔记 OOAD面向对象的分析和设计介绍 2011/10/9
友情推荐 更多
破博客 文官洗碗安天下,武将打怪定乾坤。多么美好的年代,思之令人泪落。
Mr.5's Life 白天是一名程序员,晚上就是个有抱负的探索者
行知-追寻技术之美 关注大数据,分布式系统
我爱编程 编程成长轨迹
Cynthia's Blog 学习笔记 知识总结 思考感悟
 
欢迎关注我的公众号 IT宅
关于IT宅 文章归档

IT宅中的文章除了标题注明转载或有特别说明的文章,均为IT宅的技术知识总结,学习笔记或随笔。如果喜欢,请使用文章下面提供的分享组件。转载请注明出处并加入文章的原链接。 感谢大家的支持。

联系我们:admin@itzhai.com

Theme by arthinking. Copyright © 2011-2015 IT宅.com 保留所有权利.