记一次线上问题 → 事务去哪了

  • 时间:
  • 浏览:0
  • 来源:大发快3_快3手机app下载_大发快3手机app下载

开心一刻

  小羊:哎呀,前面有奶喝

  狗妈:这谁呀,走开

  小羊:我想要喝点,能为甚么的嘛

  狗妈:你喝就喝,咋还上头了呢?

  小羊:真香!

  狗妈:这羊犊子,真硬核!

问题图片背景

  一天早上,楼主兴致勃勃的逛着园子的就让,右下角的 QQ 头像嘀嘀嘀的闪了起来,定睛一看,哎我去,肾要就让刚开始疼了,后要,头要就让刚开始疼了

  客服 MM:太躺,有个客户充值成功后,赠送的积分先要到账

  楼主:是后要客户等级过高 ,不满足资格 ?

  客服 MM:客户等级是够的,他就让的积分都正常到账了

  楼主:就让的积分都到账了 ? 哪个客户,我去看看

  客服 MM:客户名是:xxx,对应的单号是:xxx,找到原因了跟你说下

  楼主:好的,找到原因了第一时间通知你

泰坦是楼主在公司内的花名,也是楼主的 LOL 本命英雄,慢慢的被传成太躺了,楼主也很无奈;
有小伙伴问楼主,你和客服 MM 那先

关系,光看一遍头像闪动就肾疼了 ?

  你你是什么问题图片问得好,改天楼主我想要加鸡腿,觉得楼主和客服觉得挺熟悉的,工作交流挺多的,否则仅限于同事关系! 吾乃心系天下之人,岂能被儿女情长所困 ? 只可惜客服 MM 已名花有主,不然就,嘿嘿嘿,我门 懂的(是那姓吾的小子心系天下,楼主不姓吾!)

问题图片避免

  积分赠送是最近新上的另三个白 功能,上了后要另另三个白 星期了,到目前为止,也就你你是什么客户反馈了你你是什么问题图片,另外你你是什么客户就让的积分后要赠送到账了的,应该是触发了其他未考虑到的边界条件,产生了异常,原因积分未写入成功,照理来说,这应该是另三个白 事务,要么都成功,要么后要成功呀

  就让你你是什么功能后要楼主开发的,出于快速避免问题图片的考虑,楼主就找到了对应的开发同事小李,跟你说明了下情况,我想要去排查下那先 原因

  过了一会,小李找到了楼主,就让刚开始了他的排查分享

  小李:太躺,我看一遍下日志,就让 xxx 情况未考虑到,原因加积分记录的就让抛异常了

  楼主:xxx 情况觉得比较特殊,一般先要考虑到,否则为那先 存款成功了,积分却没加成功,你用了异步不 care 结果的避免 ?

  小李:我是同步避免的,照理来说,应该要回滚的

  楼主:那就奇了怪了,你把写入积分的法律辦法 给我下,我去看看代码

  几分钟就让,楼主找到了小李,跟你说了下为甚么改,否则我想要把边界限制的避免也打上去,走紧急流程升到了线上

  问题图片避免后,小李又找到了楼主

  小李:太躺啊,为那先 就让事务未回滚,而按你说的先要改就让事务就会回滚了 ?

  楼主:你去把你的椅子拿过来,我跟你好好讲讲!

问题图片复现

  注意啊,这后要说升级了就让线上又总出 了同样的问题图片,就让楼主为了我门 儿更好的了解你你是什么问题图片,模拟下当时的场景

  数据库版本 5.7.21 、存储引擎 InnoDB 、隔离级别 RR 、spring的传播机制 REQUIRED 、声明式事务 @Transactional 

  完整性代码:data-init,里边的 TransactionMissTest ,关键代码如下

/**
 * 存款
 * 引入积分就让的避免
 * @param loginName
 * @param amount
 * @return
 */
@Override
@Transactional(rollbackFor = Exception.class)
public TranMissCredit deposit(String loginName, BigDecimal amount) {
    TranMissCredit credit = creditMapper.getByLoginName(loginName);
    BigDecimal creditAfter = credit.getCredit().add(amount);

    TranMissCreditLog creditLog = new TranMissCreditLog(loginName, credit.getCredit(),
            amount, creditAfter, "充值: " + amount);
    credit.setCredit(creditAfter);

    creditMapper.update(credit);
    int count = creditLogMapper.insert(creditLog);

    return credit;
}

/**
 * 存款
 * 引入积分后的新增的法律辦法


 * @param loginName
 * @param amount
 * @param integration
 * @return
 */
@Override
public TranMissCredit deposit(String loginName, BigDecimal amount, int integration) {
    TranMissCredit credit = deposit(loginName, amount);             // 复用就让的存款逻辑

    // 下面是新增的积分业务
    int integrationAfter = credit.getIntegration() + integration;
    TranMissIntegrationLog log = new TranMissIntegrationLog(loginName, credit.getIntegration(),
            integration, integrationAfter, "充值赠送积分: " + integration);
    credit.setIntegration(integrationAfter);

    creditMapper.update(credit);
    integrationLogMapper.insert(log);
    return credit;
}


// 调用的地方,大约Controller
@Autowired
private IDepositService depositService;

@Test
public void deposit() {

    // 积分引入前的调用
    // TranMissCredit credit = depositService.deposit("zhangsan", new BigDecimal(3000));

    // 积分引入后的调用
    TranMissCredit credit = depositService.deposit("zhangsan", new BigDecimal(3000), 10);

}
View Code

  看上去好像没毛病吧,楼主你后要蒙我了把 ? 蒙没蒙你,咱们找焦点访谈

  我门 儿先看下初始情况,目前先要客户 zhangsan ,其额度 3000 ,积分 10 

  我门 儿来手动造个异常,模拟边界条件的触发,修改新增的 deposit 法律辦法

  我门 儿来看看结果

  哟嚯,额度加成功了,积分却没加成功,事务没生效!是后要有点懵 ?

问题图片分析

  我门 儿仔细观察下 deposit 法律辦法 ,另三个白 有 @Transactional 修饰,另三个白 先要,就这另三个白 差别;虽说先要这另三个白 差别,但 Spring 却在幕后替我门 儿完成了什么都事情

  Spring 事务原理

    关于你你是什么,我相信我门 儿都能答上来其他,底层实现就让动态代理(你还不知道动态代理 ?那还不赶紧去看:设计模式之代理,手动实现动态代理,揭秘原理实现)

    当 Spring 检查到 @Transactional ,会给目标对象创建另三个白 代理对象,否则在代理对象中给目标对象中被 @Transactional 修饰的法律辦法 织入事务增强避免,类似那我

    就让目标对象中先要被 @Transactional 修饰的法律辦法 ,在代理类中是咋样的了 ? 既然先要被 @Transactional ,说明不时要事务增强避免嘛,那就直调呗

    回到我门 儿的案例,代理对象与被代理对象之间的调用如下

    还都可否看出来,目标对象新增的法律辦法  TranMissCredit deposit(String loginName, BigDecimal amount, int integration) 在代理对象内是先要织入事务的,也就让默认的自动提交,先要异常抛出就让的数据库操作后要自动提交的,不用因里边的异常而回滚

    觉得后要事务丢失了,就让根本就都越来越另三个白 事务中

  再次校验

    不就让 Spring 事务,什么都的 AOP 也都一样,代码中直接操作的往往后要目标对象,就让目标对象的代理,通过代理对象来间接操作目标对象,而在代理对象中我门 儿还都可否做其他前置然就让置的增强避免,不信 ? 我门 儿再次找焦点访谈

    打个断点,看看就知道了

    注入到 TransactionMissTest 的觉得是代理对象

    我门 儿在 TranMissCredit deposit(String loginName, BigDecimal amount) 上打个断点,否则某种法律辦法 各调用一次,来看看调用链有那先 不一样

    以 depositService.deposit("zhangsan", new BigDecimal(3000)); 法律辦法 调用时

    此时调用链包含事务拦截器,有事务的调用链

    以 depositService.deposit("zhangsan", new BigDecimal(3000), 10) 法律辦法 调用时

    此时调用链中先要事务拦截器,先要事务的调用链

    是后要很明了了,so easy

总结

  1、正常上线流程

    线上问题图片 → 问题图片定位 → 问题图片复现 → 问题图片修复 → 转测试 → 测试通过升线上

    而后要像文中说的先要轻描淡写

  2、事务去哪了

    Spring 事务的底层实现就让动态代理,是通过代理的法律辦法 对目标对象做前后的增强避免,前置开启事务、后置提交(回滚)事务;

    增强避免在代理对象内,而后要在目标对象内,若目标对象的法律辦法 先要被 @Transactional 修饰,则在代理对象的代理法律辦法 内不用有关于事务的增强避免,就让直接调用目标对象的法律辦法 ,先要后续的数据库操作就后要在另三个白 事务中了

    后要事务消失了,就让都越来越同另三个白 事务了

猜你喜欢

建筑材料青瓦铺设方法与青砖砌筑方法,传承古典美

核心提示:小青瓦在北方地区又叫阴阳瓦,在南方地区叫蝴蝶瓦,俗称布瓦,是有一种弧形瓦。青瓦给人以素雅,沉稳,古朴,宁静的美感,是修建楼台、宫殿榭枋、亭廓以及各种园林建筑的首选材料

2020-01-25

华为方舟编译器开源官网正式上线

IT之家8月31日消息今日,华为方舟编译器开源官网正式上线(网址为https://www.openarkcompiler.cn/home)。华为方舟编译器开源官网概述显示,方舟

2020-01-25

谷歌DeepMind欲开发识别乳腺癌的AI技术:已获得3万名女性的乳房X线照片

据福布斯报道,DeepMind从日本东京慈恵会医科大学附属病院(JikeiUniversityHospital)获得了60 7年-2018年间约3万名一个女人患者的乳房x线照

2020-01-25

科学家称量子计算机速度存在理论上限

北京时间1月19日消息据国外媒体报道,过去200年间,标准计算机补救器的带宽不断提升。但近年来,这项技术的局限逐渐开始英文英文显露:芯片可能无法做得更小,元件也无法排得常抓,刚

2020-01-25

商务部:中美经贸高级别磋商双方牵头人通话讨论遗留问题

商务部今天举行例行新闻发布会,在回答中美经贸磋商大大问题时,商务部新闻发言人高峰介绍:4月3号到5号,刘鹤副总理与美国贸易代表莱特希泽、财政部长姆努钦在华盛顿一块儿主持第九轮中

2020-01-25