基于跨数据库的事务的一个讨论,希望参考下大家的意见
多个数据进行数据操作, 基于性能方面的考虑首先排除掉了分布式事务,
后来参考了 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
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;
}
}
begin;
//dosomething A 库
commit;
flag =true;
}catch(Exception e){
rollback;
}
if(flag){
try{
begin;
//dosomething B 库
commit;
}catch(Exception e){
//手工回滚 A 库
rollback;
}
}
后者似乎更加简单 方便, 前者虽然可以让数据最终达到一致,但是不可避免的是由于数据获取其他的因素必须回滚 前者似乎并没有达到预期的效果.
系统大家讨论下 两种方式的利于弊. 同时也讨论下夸库事务是否有更好的办法