我正在尝试在我的代码中实现事务。但即使在其中一个模型($ timesheet模型)验证失败后,事务也不会回滚。 以下是我的代码:
public function actionCreate() {
$model = new Timesheet();
$subscriber = null;
// get current subscriber id.
$subscriber_id = General::getSubscriberIdByUserId(\Yii::$app->user->id);
if ($subscriber_id > 0) {
$subscriber = Subscriber::findOne($subscriber_id);
if ($subscriber) {
$model->subscriber_id = $subscriber->id;
$model->subscriber_name = $subscriber->name;
}
}
if ($model->load(Yii::$app->request->post())) {
//Transaction starts here
$transaction = Yii::$app->db->beginTransaction();
try
{
if (!empty($model->date)) {
$model->date = General::convertDDMMYYYYToMysqlCompliant($model->date);
$model->user_id = \Yii::$app->user->id;
}
// to find total hours of the day already logged
$total_daily_hours = (Timesheet::find()->where(['user_id' => Yii::$app->user->id])->andWhere(['date' => $model->date])->sum('hours'));
$model->hours = ($model->hours + $model->minute);
$dayofweek = date('w', strtotime($model->date));
if($dayofweek == 6)
{
$monday = date('Y-m-d', strtotime('last monday', strtotime($model->date)));
}
else
{
$monday = date('Y-m-d', strtotime('this monday', strtotime($model->date)));
}
$saturday = date('Y-m-d', strtotime('this saturday', strtotime($model->date)));
// to find total hours of the week already logged
$team_member_weekly_hours = Timesheet::find()->where(['user_id' => \Yii::$app->user->id])->andWhere(['between', 'date', $monday, $saturday])->sum('hours');
$role = \Yii::$app->authManager->getRolesByUser(\Yii::$app->user->id);
if(array_key_exists('intern', $role) == false)
{
$TEAM_MEMBER_WEEK_LIMIT = 48;
}
else
{
$TEAM_MEMBER_WEEK_LIMIT = Timesheet::TEAM_MEMBER_WEEK_LIMIT;
}
if ((
(Timesheet::PER_DAY_HOURS_LIMIT) >= ($total_daily_hours + $model->hours)
|| ((Timesheet::PER_DAY_HOURS_LIMIT) >= ($total_daily_hours + $model->hours)
&& (array_key_exists('team-member', $role)))
)
&& (Timesheet::blockMonthEntry($model->date) == true)
&& ($TEAM_MEMBER_WEEK_LIMIT >= $team_member_weekly_hours + $model->hours)
&& ($model->hours != 0))
{
// get user hourly rate
$usertohourlyrate = UserToHourlyRate::getHourlyRateByUserId($model->user_id);
$model->total_amount = $usertohourlyrate * $model->hours;
$model->hourly_rate = $usertohourlyrate;
// echo "<pre>";var_dump($model);die;
if($model->save())
{
$model_id = $model->id;
}
// echo "$model_id";
//For Notification
$userToNotify = [];
$user_id = \Yii::$app->user->id;
$userForNotify = UserToSubscriber::find()->select('senior_user_id')->where(['user_id'=>$user_id])->all();
if($userForNotify != NULL)
{
$userToNotify = [];
foreach($userForNotify as $ufn){
array_push($userToNotify,$ufn->senior_user_id);
}
foreach($userToNotify as $value)
{
$noticemodel = new Notifications();
$noticemodel->user_id = $value;
$noticemodel->relation_name = 'timesheet';
$noticemodel->relation_id = $model->id;
$noticemodel->notice_abstract = "Timesheet Created Notification.";
$noticemodel->action = '0';
$noticemodel->created_on = date('Y-m-d h:i:s');
$noticemodel->save();
}
}
//
if (General::ifUserPermitted('timesheetAutoTimesheetApproval')) {
// echo "in if";
// timesheet auto approval
// WIP update
General::onTimesheetChange($model->job_id, $model->user_id, $model->date, "timesheet");
//For update timesheet model
$timesheet_model = Timesheet::findOne($model_id);
echo "<pre>";var_dump($timesheet_model);//die;
$timesheet_model->action_taken_at = date("Y-m-d h:m:s");
$timesheet_model->action_taken_by = \Yii::$app->user->id;
$timesheet_model->status = "Approved";
echo "<pre>";var_dump($timesheet_model);
$timesheet_model->save();
if($timesheet_model->save())
{
echo "True";
}
else
{
echo "False";
$errors = $timesheet_model->errors;
echo "<pre>";var_dump($errors);
}
//For Notification
if($userForNotify != NULL)
{
$userToNotify = [];
foreach($userForNotify as $ufn){
array_push($userToNotify,$ufn->senior_user_id);
}
foreach($userToNotify as $value)
{
$notification = Notifications::find()->where(['user_id'=>$value , 'relation_id'=>$model->id, 'notice_abstract'=>'Timesheet Created Notification.'])->one();
if($notification != NULL)
{
$notification->action = '1';
$notification->save();
}
}
}
//
}
if (array_key_exists('team-member', $role)) {
$msg = "Entry Inserted Successfully and Your remaining weekly hours is <b>" . ((Timesheet::TEAM_MEMBER_WEEK_LIMIT) - ($team_member_weekly_hours + $model->hours)) . " hrs.</b>";
} else {
$msg = "Entry Inserted Successfully and Your remaining hours is <b>" . ((Timesheet::PER_DAY_HOURS_LIMIT) - ($totel_hours + $model->hours)) . " hrs.</b>";
}
\Yii::$app->session->setFlash('success', $msg);
$transaction->commit();
return $this->redirect(['view', 'id' => $model->id]);
}
elseif (Timesheet::blockMonthEntry($model->date) != true) {
$msg = "This date has been blocked";
}elseif ($totel_hours == (Timesheet::PER_DAY_HOURS_LIMIT) || $team_member_weekly_hours == (Timesheet::TEAM_MEMBER_WEEK_LIMIT)) {
$msg = "Your Daily hours is over";
} elseif (($totel_hours + $model->hours) > Timesheet::PER_DAY_HOURS_LIMIT) {
$msg = "Your remaining daily hours only is <b>" . ((Timesheet::PER_DAY_HOURS_LIMIT) - $totel_hours) . " hrs.</b>";
} elseif ($model->hours == 0) {
$msg = "Please select hours";
} else {
$msg = "Your remaining Weekly hours only is <b>" . ((Timesheet::TEAM_MEMBER_WEEK_LIMIT) - $team_member_weekly_hours) . " hrs.</b>";
}
\Yii::$app->session->setFlash('error', $msg);
list($model->hours, $minute) = explode('.', $model->hours);
$model->minute = "0." . $minute;
if(empty($model->date)){
$model->date = date('j/n/Y');
}else{
$model->date = General::convertMysqlDateToDDMMYYYY($model->date);
}
return $this->render('create', [
'model' => $model,
'master_mode' => Yii::$app->user->can('associateSubscriberWithDetails'),
]);
}
catch(Exception $e)
{
\Yii::$app->session->setFlash('error', $e);
$transaction->rollBack();
}
//Transaction ends here
}
else
{
if(empty($model->date)){
$model->date = date('j/n/Y');
}else{
$model->date = General::convertMysqlDateToDDMMYYYY($model->date);
}
return $this->render('create', [
'model' => $model,
'master_mode' => Yii::$app->user->can('associateSubscriberWithDetails'),
]);
}
}
我该怎么办?在哪里修改代码? $ timesheet模型在更新模型时失败,但模型在未回滚之前保存。
如果任何一个模型save()失败,我想回滚所有save()。
答案 0 :(得分:0)
当执行此方法失败时,Yii save()
不会抛出异常(对于异常)。因此,您必须检查save()
的结果,并在发生故障时抛出异常。
在save()
语句中使用try{}catch(Exception $e){}
时,请使用此处:
if (!$model->save()) {
throw new Exception("Trigger transaction rollback");
} else {
// something
}