由真实场景联想到的对事务认识的二三事

真实场景:公司b2c app测试过程中,前端测试发现一个bug--从虚拟钱包转账到微信,微信收款成功,虚拟钱包金额无扣减
1.认识的误区一:事务里的资源都是能够rollback的.

问题代码逻辑如下

//伪代码
begin translation
//调用微信支付接口
boolean callResult= remote.transf(......);
if(callResult)
{
   //操作本地数据库
   boolean payResult= local.pay(......);
   if(payResult)
   {
      commit;
   }
   else
   {
     rollback;
   }
}
else
{
  rollback
}
end translation



问题原因:微信转账接口对调用方而言,不支持rollback,因此这是一个"伪事务",
真正的事务应当是无论是本地事务还是分布式事务
参与事务的任何一个资源管理器关联的资源是支持commit和rollback的;

解决方案:调整调用次序

//伪代码
begin translation
//操作本地数据库
boolean callResult = local.pay(......);
if(callResult)
{
   //调用微信支付接口
   boolean payResult= remote.transf(......);
   if(payResult)
   {
      commit;
   }
   else
   {
     rollback;
   }
}
else
{
  rollback
}
end translation

 


2.认识误区二:事务是有效的
http://www.cnblogs.com/xiaoyuanding/p/3947986.html

分布式事务可以简化为本地事务
简化为本地事务有效吗?
由于调用了两次删除文件的操作,所以无论怎么调整调用次序,本地事务都不起作用,因此使用事务跟不用事务结果一样

解决方案:借助持久化消息队列投递消息或定时任务+消息状态字段来删除文件,如遇不成功,不断重试,直到成功。

posted @ 2016-06-17 16:37  songcan  阅读(178)  评论(0编辑  收藏  举报