一个纠结的问题!两个表操作如何实现原子性

狗头666 发布于 2012/02/14 18:00
阅读 884
收藏 0
PHP

在PHP里面有表a和表b,需要实现的操作如下

操作1:在表a里面插入一条记录并获取这条记录的主键值,如果不成功则不执行后面的操作;

操作2:将这个主健值插入表b,如果不成功则取消操作1

操作2怎么取消操作1呢,操作1都已经成功了.....

以下是问题补充:

@狗头666:表a和表b在两个数据库里面 (2012/02/16 11:24)
@狗头666:@weekend @SunSteven “分布式事务”,这个我查了下好像很复杂啊,你们能给举个例子不? (2012/02/16 11:34)
加载中
3
浪客Dandy
浪客Dandy

php我不知道

但总的来说你把他们放在一个事务里就可以了

雷志伟
雷志伟
这个还真跟PHP没关系.
1
飞晏
飞晏
$db = new db();
$db->query('SET AUTOCOMMIT=1');
$db->query('BEGIN');
$db->query('INSERT INTO a VALUES(xxx)');
$id = $db->insert_id(); //返回自增主键
if( $id ) {
    $db->query('INSERT INTO b VALUES('.$uid.')');
    $db->query('COMMIT');
} else {
    $db->query('ROLLBACK');
}
0
狗头666
狗头666
用回滚?
飞晏
飞晏
操作2的话可以考虑用mysql事物
0
Yisen
Yisen

这不是事务的做法吗

楼主这不是有武器不用自己去打铁?

0
DanielTo
DanielTo
这样的业务需求用关联可以很好地解决问题啊。
0
狗头666
狗头666

额,是这样,我没说清楚问题,这两个表在不同的数据库里面,不能把两个操作放在一个事务里面

我现在是这样做的,不知道有没有更好的方法

<?php
function operate2($p_id)
{
	$db = new PDO( DSN2 );
	if($db->exec('INSERT INTO tab2(b) VALUES('.$p_id.');'))
		return TRUE;
	else
		return FALSE;
}
$db = new PDO( DSN1 );
$db->beginTransaction();
$db->exec('INSERT INTO tab1(a) VALUES(1);')
$p_id = $db->lastInsertId();
if(operate2($p_id))
	$db->commit();
else
	$db->rollBack();
?>

狗头666
狗头666
@mahone : 额,我没加错误处理代码,单单就这个问题,这个代码应该没什么问题了。
mahone
mahone
你确定现在你写的这样的代码ok?当然,我也不知道是否ok。。。
0
w
weekend
用分布式事务
0
Monkey
Monkey
在补充一条,如果取消1失败了呢。程序是不是僵死在那里了啊。
Monkey
Monkey
@cers000 : 这不是一个技术问题,而是一个业务问题。
狗头666
狗头666
@Monkey : 什么意思?有点没看明白
Monkey
Monkey
@cers000 : 这个就应该是逻辑出问题了,不应这么,处理问不是这么处理的。解决一个问题同上又带来一个新的问题。
狗头666
狗头666
不能这样无限制的考虑下去吧, 那要是检测“取消1失败”的操作失败了呢, 要是检测“检测“取消1失败”的操作失败”的操作失败了呢
0
飞晏
飞晏

1. 存储过程(尽量不用)

2. 两个事务

3. 分布式,比如用Gearman。

0
freish
freish
学数据库的时候没学事务的ACID特性( 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)   )?
返回顶部
顶部