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

  • 时间:
  • 浏览:0
  • 来源:大发快3_快3在线稳定计划_大发快3在线稳定计划

开心一刻

  小羊:哎呀,前面有奶喝

  狗妈:这谁呀,走开

  小羊:我就喝点,能怎么能 的嘛

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

  小羊:真香!

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

问提背景

  一天早上,楼主兴致勃勃的逛着园子的以前,右下角的 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(1150));

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

}
View Code

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

  .我.我先看下初始状态,目前只有客户 zhangsan ,其额度 1150 ,积分 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(1150)); 法律法律依据调用时

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

    以 depositService.deposit("zhangsan", new BigDecimal(1150), 10) 法律法律依据调用时

    此时调用链中那末事务拦截器,那末事务的调用链

    是也有很明了了,so easy

总结

  1、正常上线流程

    线上问提 → 问提定位 → 问提复现 → 问提修复 → 转测试 → 测试通过升线上

    而也有像文中说的那末轻描淡写

  2、事务去哪了

    Spring 事务的底层实现假如有一天动态代理,是通过代理的法律法律依据对目标对象做前后的增强除理,前置开启事务、后置提交(回滚)事务;

    增强除理在代理对象内,而也有在目标对象内,若目标对象的法律法律依据那末被 @Transactional 修饰,则在代理对象的代理法律法律依据内不需要有关于事务的增强除理,假如有一天直接调用目标对象的法律法律依据,那末后续的数据库操作就也有在好几个 事务中了

    也有事务消失了,假如有一天找不到同好几个 事务了

猜你喜欢

Lyft发布无人驾驶汽车开发数据库,包括5.5万张3D高清图像

IT之家7月29日消息为了有有助于于无人驾驶汽车的发展,Lyft今天发布了一组无人驾驶汽车的开发数据,该公司称这以数据库是这类于数据中规模最为庞大的。它以现有的nuScenes

2020-01-23

隐形守护者全章节全结局怎么达成 全结局达成攻略

隐形守护者全章节全结局要为何达成,每个章节的完全剧情要为何解锁呢,这里亲戚亲戚朋友来看下完全章节剧情的解锁措施 。序章1、选【保持沉默】2、选【都可能性过去了,问这麼多干嘛?

2020-01-23

[区块链] 拜占庭将军问题 [BFT]

背景:拜占庭将军问提什么都人们机会听过,但别问我具体是那此意思。非要 究竟那此是拜占庭将军问提呢?本文从最通俗的故事讲起,并对该问提进行抽象,并告诉朋友拜占庭将军问提为那此在

2020-01-23

传WP9将是智能机和平板通吃系统,2015年发布

微软正忙着在明年推出WindowsPhoneBule(WP8.1)大更新,但现在已传来了有关2015年WindowsPhone9的消息,据称WP9将是并肩支持智能机和平板电脑的

2020-01-23

春天来了,中国乡村最美的花开咯!

春天,初阳灼目,柔风和煦,散去了冬季的凉意,吹来了阵阵花香。大地草长莺飞,中国辽阔的土地之上,七彩的春天序幕拉开,油菜花、桃花、杏花、梨花……你偏爱哪并与否?江西婺源油菜花层层

2020-01-23