Db transaction to slow so that the next query will be executed just before the previous query commited

I have a function that utilize db transaction like below,

public function actionInvpost($id) {
        $request = Yii::$app->request;

        $model = $this->findModel($id);

        $connection = Yii::$app->db;
        $transaction = $connection->beginTransaction();

        try {
            if ($model->branchTarget->creditLimit < $model->branchTarget->getCreditBalance() + $model->getTotalCharges()) {
                throw new Exception(Yii::t('app', '{name} is over the credit limit, it cannot be invposted!', ['name' => $model->branchTarget->name]));
            } else {
                if (FormHeader::UNPOSTED == $model->status) {
                    $model->status = FormHeader::INVPOSTED;
                    if ($model->save()) {
                        // Insert FormStatus
                        $formStatus = new FormStatus();
                        $formStatus->headerFk = $model->getPrimaryKey();
                        $formStatus->status = FormStatus::FORM_INVPOSTED;
                        $formStatus->memo = '## Invpost by ' . Yii::$app->user->identity->username . ' ##';

                        if (!$formStatus->save()) {
                            throw new Exception(Yii::t('app', 'Error in saving branch transfer status!'));
                        }


                        $transaction->commit();

                        Yii::$app->getSession()->setFlash('success', $model->formNo . ' ' . Yii::t('app', 'is successfully invposted.'));

                        if ($request->isAjax) {
                            /*
                             *   Process for ajax request
                             */
                            Yii::$app->response->format = Response::FORMAT_JSON;

                            return ['forceClose' => true, 'forceReload' => '#crud-datatable-pjax'];
                        } else {
                            /*
                             *   Process for non-ajax request
                             */
                            return $this->redirect(['view', 'id' => $model->id]);
                        }
                    } else {
                        throw new Exception(Yii::t('app', 'Error in saving branch transfer!'));
                    }
                } else {
                    throw new Exception(Yii::t('app', 'Error for multiple submission!'));
                }
            }
        } catch (Exception $e) {
            $transaction->rollBack();
            if ($request->isAjax) {
                /*
                 *   Process for ajax request
                 */
                return [
                    'title' => Html::icon('glyphicon glyphicon-exclamation-sign white') . ' ' . Yii::t('app', 'Invpost branch transfer'),
                    'size' => 'normal',
                    'backgroundHeader' => 'btn-danger',
                    'content' => Html::tag('span', 'Exception error! ' . $e->getMessage(), ['class' => 'text-danger']),
                    'footer' => Html::button(Html::icon('glyphicon glyphicon-remove') . ' ' . Yii::t('app', 'Close'), ['class' => 'btn btn-default pull-left', 'data-dismiss' => 'modal'])
                ];
            } else {
                /*
                 *   Process for non-ajax request
                 */
                Yii::$app->getSession()->setFlash('error', 'Exception error! ' . $e->getMessage());

                return $this->redirect(['view', 'id' => $model->id]);
            }
        }
    }

Above code should handle the possibility of double clicking of the button that call this function. However, I am still getting this double click problem.

 ...	FORM_INVPOSTED	91	2021-07-03 12:49:35
...	FORM_INVPOSTED	91	2021-07-03 12:49:45	

Does the transaction is the problem?

Any suggestion?

Thank you in advance.

Hi adinugro, this shouldn’t be slow, or are you executing some beforeSave and beforeSave?

As for the double click, you could solve it with JS on client side. Just block the button after the first submission click, like so:

$('form').submit(function(){
    $('input[type=submit]', this).attr('disabled', 'disabled');
});

This code comes from this StackOverflow answer: How can I prevent a double submit with jQuery or Javascript? - Stack Overflow

I have beforeSave, but it should not be slow

 public function beforeSave($insert) {
        if ('XXXX' == strtoupper(substr($this->formNo, -4))) {
            $this->formNo = $this->getNextCode(substr($this->formNo, 0, -4), 4);
        }

        // Update discount
        if (empty($this->discountText)) {
            $this->discount = 0;
        } else if (strpos($this->discountText, '%') === false) {
            $this->discount = intval($this->discountText);
        } else {
            $this->discount = intval(intval(str_replace('%', '', $this->discountText)) * $this->totalDetails / 100);
        }

        return parent::beforeSave($insert);
    }

I execute the function from a link below

$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Invpost'), 'template' => Html::tag('span', Html::a(
                        Html::icon('glyphicon glyphicon-folder-close') . ' ' . Yii::t('app', 'Invpost'), Url::to(['invpost', 'id' => $model->id]), [
                    'class' => 'btn btn-xs btn-info',
                    'title' => Yii::t('app', 'Invpost'),
                    'data-pjax' => 0,
                    'data-method' => 'post',
                    'data-confirm' => Yii::t('app', 'Are you sure you want to set the status to Invposted?'),
                        ]
                ), ['class' => 'pull-right', 'style' => 'margin-right: 25px;'])];

Can I hide the link after click?

Yes, you can with some Javascript.