基于跨数据库的事务的一个讨论,希望参考下大家的意见

多个数据进行数据操作, 基于性能方面的考虑首先排除掉了分布式事务,

后来参考了 ebay 的  用消息队列和消息应用状态表来消除分布式事务 原文可以看这里 http://rdc.taobao.com/blog/cs/?p=671

大致是这样的一个过程:

begin;
INSERT INTO transaction VALUES(xid, $seller_id, $buyer_id, $amount);
put_to_queue “update user(“seller”, $seller_id, amount);
put_to_queue “update user(“buyer”, $buyer_id, amount);
commit;
for each message in queue
begin;
SELECT count(*as cnt FROM message_applied WHERE msg_id = message.id;
if cnt = 0 then
if message.type = “seller” then
UPDATE user SET amt_sold = amt_sold + message.amount WHERE id = message.user_id;
else
UPDATE user SET amt_bought = amt_bought + message.amount WHERE id = message.user_id;
end
INSERT INTO message_applied VALUES(message.id);
end
commit;
if 上述事务成功
dequeue message
DELETE FROM message_applied WHERE msg_id = message.id;
end

end

 

但是这样子搞 如果 操作A库成功了 而操作B库失败了  我可以在很短时间内重试, 如果重试失败了的话, 我必须对A 库的数据进行手工回滚 , 但是随后提出的另外的一个意见 ,于其如此不如像这样的一个结构

 boolean flag = false;

try{
  begin;
 //dosomething A 库
  commit;
  flag =true;
}catch(Exception e){
  rollback;
}
if(flag){
try{
  begin;
  //dosomething B 库
  commit;
}catch(Exception e){
 //手工回滚 A 库
 rollback;
}
}

 

 后者似乎更加简单 方便, 前者虽然可以让数据最终达到一致,但是不可避免的是由于数据获取其他的因素必须回滚 前者似乎并没有达到预期的效果. 

系统大家讨论下 两种方式的利于弊.  同时也讨论下夸库事务是否有更好的办法

 

 

posted @ 2011-09-24 19:08  雨中漫步的太阳  阅读(564)  评论(0编辑  收藏  举报