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

  • 时间:
  • 浏览:1
  • 来源:大发快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(5000));

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

}
View Code

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

  让我们我们都都 先看下初始状况,目前都还还可以了客户 zhangsan ,其额度 5000 ,积分 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(5000)); 措施调用时

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

    以 depositService.deposit("zhangsan", new BigDecimal(5000), 10) 措施调用时

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

    是都还还可以很明了了,so easy

总结

  1、正常上线流程

    线上那此的大问题 → 那此的大问题定位 → 那此的大问题复现 → 那此的大问题修复 → 转测试 → 测试通过升线上

    而都还还可以像文中说的如此轻描淡写

  2、事务去哪了

    Spring 事务的底层实现已经 动态代理,是通过代理的措施对目标对象做前后的增强外理,前置开启事务、后置提交(回滚)事务;

    增强外理在代理对象内,而都还还可以在目标对象内,若目标对象的措施如此被 @Transactional 修饰,则在代理对象的代理措施内太久有关于事务的增强外理,已经 直接调用目标对象的措施,如此后续的数据库操作就都还还可以在另两个事务中了

    都还还可以事务消失了,已经 没哟同另两个事务了

猜你喜欢

将良心进行到底!Oculus商店在英国推出退款政策

并非 他们儿赶在taobao上疯狂购物,其中一大意味着着是不满意都时需退,但会 目前绝大每项的软件销售平台能不能 像内部销售平台那样都时需退货退款。不过现在,O

2020-01-17

M. Zischler数据,M. Zischler新闻,M. Zischler视频,M. Zischler身价

M.ZischlerM.Zischler俱乐部:皮平斯列特国籍:德国身高:CM位置:中场年龄:50岁体重:KG号码:23号生日:1989-09-24惯用脚:赛季俱乐部上场首发进

2020-01-17

大冶市追回失盗文物清代香案

核心提示:邹氏宗祠一角汉白玉香案大冶市邹氏宗祠镇祠之宝汉白玉香案不翼而飞,村民自发组成寻宝队,历时3年发现其踪迹后报案,后在文物部门和警方努力下,终将其找回。 大冶市邹氏宗祠“

2020-01-17

楷和医心\前列腺癌的风险因素\泌尿外科专科医生 林建文

前列腺癌是香港男性最常见癌症之一,二○一六年有超过一千九百宗新症。多年来研究人员不断尝试找出癌症的成因,近期《国际癌症杂志(InternationalJournalofCanc

2020-01-17

绝地求生刺激战场催化剂怎么获得 刺激战场催化剂获得方法

绝地求生刺激战场催化剂为什么在么在获得?绝地求生刺激战场小春雷为什么在么在制作?一块儿来看看刺激战场催化剂获得法子 。刺激战场催化剂获得法子 1、每天通过帮助好友制作武器,

2020-01-17