Transactions Yii2当使用事务进行多步骤注册时,那么就退一步如何检索数据
当前实施情况 目前我正在使用多步骤注册,我总共有3个步骤 最后一步是确认输入的所有数据,然后提交 现在,我在步骤1的最开始使用transaction,如:Transactions Yii2当使用事务进行多步骤注册时,那么就退一步如何检索数据,transactions,yii2,Transactions,Yii2,当前实施情况 目前我正在使用多步骤注册,我总共有3个步骤 最后一步是确认输入的所有数据,然后提交 现在,我在步骤1的最开始使用transaction,如: $transaction = Yii::$app->db->beginTransaction(); 如果在我使用的任何点执行失败 $transaction->rollBack(); 从数据库回滚所有条目的步骤 现在,如果一切都执行得很好,并且在最后一步中,用户确认输入的数据并提交,我会将所有数据保存在db中,如: $tr
$transaction = Yii::$app->db->beginTransaction();
如果在我使用的任何点执行失败
$transaction->rollBack();
从数据库回滚所有条目的步骤
现在,如果一切都执行得很好,并且在最后一步中,用户确认输入的数据并提交,我会将所有数据保存在db中,如:
$transaction->commit();
问题
现在,由于我正在使用多步骤注册,如果任何时候用户想要返回到上一步,那么如何检索填充的数据
我们无法从表中检索数据,因为直到最后一个commit语句,我们还并没有将任何内容存储到数据库中
当前解决方案
一种解决方案是使用会话存储临时数据,但我正在寻找任何其他方法如果您对每个步骤使用新操作(以及一个名为“注册”的表,即),那么对于每个操作,您可以传递注册
id
,并根据步骤编号加载字段。
因此,让我们考虑你有一个登记表,包括“代码>名称<代码> >代码>姓氏<代码> >代码>年龄<代码> >代码>性别>代码>字段,在步骤1中填写<代码>名称<代码> >代码>姓氏< /代码>,在步骤2填写<代码>年龄< /代码>和<代码>性别<代码>。您的模型将如下所示:
class Registration extends \yii\db\ActiveRecord
{
const SCENARIO_STEP1 = 'step1';
const SCENARIO_STEP2 = 'step2';
public function scenarios()
{
return [
self::SCENARIO_STEP1 => ['name', 'surname'],
self::SCENARIO_STEP2 => ['age', 'gender'],
];
}
public function rules()
{
... your validation for fields...
请注意,此处的场景非常重要,可以在精确步骤中对某些精确字段进行验证(有关您可以从中阅读的场景的更多信息)
第一步的行动如下:
public function actionStep1()
{
$model = new Registration();
$model->setScenario(Registration::SCENARIO_STEP1);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['step-2', 'id' => $model->id]);
} else {
return $this->render('step-1', [
'model' => $model,
]);
}
}
在step-1
视图中,您有需要填写的name
和姓氏
字段,其中验证只适用于场景()
方法中列出的字段。然后在第二步操作中,代码如下所示:
public function actionStep2($id)
{
$model = Order::findOne($id);
$model->setScenario(Order::SCENARIO_STEP2);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['finish', 'id' => $model->id]);
} else {
return $this->render('step-2', [
'model' => $model,
]);
}
}
。。如您所见,在第二步中,我们传递已经存在的注册模型的id
,并继续填充其属性。根据您有多少步骤,您可以从第二步重定向到第三步,或者显示finish消息并执行一些您需要的其他逻辑
我认为您对如何使用事务的想法有点错误,因为事务是保存数据库中的行的方式(防止在进行更改时在其他地方更改这些行)
进行多步骤注册的另一种方法是在单个页面中包含所有步骤,并根据您的阶段显示/隐藏所需字段(例如使用JQuery)。我记得已经回答过这类问题,但找不到链接。。如果我成功了,我一定会更新我的答案
希望我的回答是有帮助的为了尽可能多地保留解决方案而不是用户会话存储,那么我会说使用ajax请求对每个步骤进行验证 更详细地说
- 用户输入url,如用户/注册#步骤1
- 填表
- 单击下一步
- 发送AJAX请求以验证发送的数据
- 如果验证成功,则转至步骤2,如“用户/注册#步骤2”
- 步骤1表单隐藏,步骤2表单使用javascript显示
- 如果验证失败,则显示消息并保持当前步骤
$transaction = Yii::$app->db->beginTransaction();
保存您的模型
最后,回滚所有更改。(成功和失败)
通过这种方式,您可以确保数据可以保存在数据库中(可能您的数据库有规则中未定义的限制),而无需实际保存任何内容
在最后一步中,您将收集所有步骤中的所有数据:
$transaction = Yii::$app->db->beginTransaction();
保存模型,并在验证后提交更改
$transaction->commit();
据我所知,如果您使用了事务,那么在您使用$transaction->commit()提交之前,它不会在db中创建任何记录;现在使用事务的原因是希望避免数据库中任何未完成的数据,比如有人在两者之间留下了注册。是的,但事务通常使用很短的时间。例如,你有一个银行账户。考虑一下你支付了一些服务,同时有人把一些钱转给你(在你提交你的交易之前,他不能这么做)。我的意思是交易是在一个脚本中进行的,所以您不能将其传递给另一个操作。。。(它将简单地回滚)
$transaction->commit();