运行结果如下,数据库没有插入新数据,事务被回滚。
save 1 | save 2 | save 3 | rollback
分散的数据处理
由于实际项目的复杂程度,导致我们的数据库操作分散在不同的Model中。
所以,实际项目的代码不会是上面的样子。
模拟需求
接收参数:
名字
性别
签名
业务处理流程:
接收参数
由发号器得到用户的uid,发号器对应数据表增加一位数字
把名字、性别、签名和上一步的uid写入用户信息表
初始化用户余额表
回滚触发时机:
初始化余额表没有传入uid导出没有写入数据
实际代码
//Controller
/**
* 测试事务-注册用户
*/
public function actionReg()
{
//获取请求
$request = Yii::$app->request;
//设定返回格式
$response = Yii::$app->response;
$response->format = yiiwebResponse::FORMAT_JSON; //返回json
//测试代码,去掉验证身份步骤
$name = $request->get("name");
$gender = $request->get("gender");
$sign = $request->get("sign");
//测试代码,省略参数校验步骤
$tr = Yii::$app->db->beginTransaction();
try {
//得到uid
$uid = App::getSeNo();
UserProfile::add($uid, $name, $gender, 1, $sign);
$user_balance = UserBalance::initUserBalance($uid);
$tr->commit(); //提交数据
} catch (Exception $e) {
//回滚
$tr->rollBack();
return $e->getMessage(); //返回自定义异常信息
}
return $user_balance;
}
//UserProfile
/**
* 添加用户信息
* @param $user_id
* @param $nikename
* @param $gender
* @param $user_type
* @param string $intro
* @return UserProfile
* @throws Exception
*/
public static function add($user_id, $nikename, $gender,$user_type,$intro="") {
$model = new UserProfile();
$model->gender = $gender;
$model->nikename = $nikename;
$model->user_id = $user_id;
$model->user_type=$user_type;
$model->intro=$intro;
$model->update_time = time();
$insert =$model->insert();
if(!$insert){
throw new Exception("没有写入用户资料");
}
return $model;
}
//UserBalance
/**
* 初始化用户的可提现余额
* @param $user_id
*/
public static function initUserBalance($user_id){
$info=self::find()->where(['user_id'=>$user_id])->one();
if(!$info ){
$model=new UserBalance();
$model->user_id = $user_id;
$model->price= "0";
$model->update_time=time();
$insert = $model->insert();
if(!$insert){
throw new Exception("没有初始化用户余额");
}
$info=$model;
}
return $info->attributes;
}
正常的结果如下
{"id":124,"user_id":1473179883,"price":"0","update_time":1473179883}
如果把初始化用户余额部分的user_id没有传递成功,返回的结果如下
"没有初始化用户余额"
我们可以针对具体情况定位到错误所在位置,及时修改。
事务(Transaction)







