摘要:第二沒有記錄日志的行為,即使出了問題也不容易排除。異常錯誤然后回到如何傳參的問題,我們可以使用閉包,貼一段偽代碼,如下執行事務業務代碼大功告成,代碼看起來有沒有更好看呢如有問題,歡迎指教。
在控制器中執行事務的時候,一般的代碼如下:
$transaction = Yii::$app->db->beginTransaction(); try { //一些業務代碼 $transaction->commit(); } catch (Exception $e) { $transaction->rollBack(); throw $e; }
于是我在想,這個代碼結構,只有//一些業務代碼 這一部分是不一樣,卻要重復很多遍,這一不是很冗余嗎? 而且 不!好!看!,于是我試著尋找解決方法,一開始在stackflow找到一個類似的提問,有方案是在model里做封裝,但是這樣做有一定問題,如產生嵌套事務等,有興趣的可以點擊這里查看該問答。
我們的Yii框架給出了一個方法transaction,乍一看好像不能解決傳參的問題,我們先不管,往下看,該方法調用方式如下:
Yii::$app->db->transaction(function() { //一些業務代碼 });
我們來看一下這個方法的源碼
/** * Executes callback provided in a transaction. * * @param callable $callback a valid PHP callback that performs the job. Accepts connection instance as parameter. * @param string|null $isolationLevel The isolation level to use for this transaction. * See [[Transaction::begin()]] for details. * @throws Exception|Throwable if there is any exception during query. In this case the transaction will be rolled back. * @return mixed result of callback function */ public function transaction(callable $callback, $isolationLevel = null) { $transaction = $this->beginTransaction($isolationLevel); $level = $transaction->level; try { $result = call_user_func($callback, $this); if ($transaction->isActive && $transaction->level === $level) { $transaction->commit(); } } catch (Exception $e) { $this->rollbackTransactionOnLevel($transaction, $level); throw $e; } catch (Throwable $e) { $this->rollbackTransactionOnLevel($transaction, $level); throw $e; } return $result; }
這個方法接受一個回調函數和事務的隔離級別,
從這里我們看出,這個方法雖然解決重復代碼,卻還有幾個問題沒有解決:
第一,這個方法拋出的異常我們需要在接收外面處理,我們不可能直接拋出,這樣對客戶端很不友好。
第二:沒有記錄日志的行為,即使出了問題也不容易排除。
第三:其實還是第一個問題,如果我們需要對每個異常做處理,在transaction方法外再嵌套一層try...catch...,那么和沒有封裝好像沒什么區別?
根據方法可擴展不可修改的原則,我們應該在自己公共方法里對這個方法進行重載,重載代碼如下:
public static function TransactionExecute(callable $function,$level=null) { try{ Yii::$app->db->transaction($function,$level); }catch (Exception $e){ //記錄日志 Yii::error($e->getMessage()); //這里可以理解成拋出自定義的異常類。 (new self())->returnWayTip(1004, "trans異常錯誤"); } }
然后回到如何傳參的問題,我們可以使用閉包,貼一段偽代碼,如下:
//執行事務 PublicFunction::TransactionExecute(function () use ($token_reward, $reward_info) { //業務代碼 $token_reward->save(0); MsgHelper::send($reward_info["post_id"], MsgHelper::SOMEONE_FINISH_REWARD, $reward_info); });
大功告成,代碼看起來有沒有更好看呢?
如有問題,歡迎指教。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/29233.html
摘要:學編程真的不是一件容易的事不管你多喜歡或是多會編程,在學習和解決問題上總會碰到障礙。熟練掌握核心內容,特別是和多線程初步具備面向對象設計和編程的能力掌握基本的優化策略。 學Java編程真的不是一件容易的事,不管你多喜歡或是多會Java編程,在學習和解決問題上總會碰到障礙。工作的時間越久就越能明白這個道理。不過這倒是一個讓人進步的機會,因為你要一直不斷的學習才能很好的解決你面前的難題...
摘要:多入口模式,多入口分為后臺前端,微信,其他或接口對接,不同的業務不同的設備進入不同的入口。對接微信公眾號,使用了一款優秀的微信非官方,系統內已集成了該,調用方式會在文檔說明,也可直接看其文檔進入深入開發。 RageFrame 為二次開發而生,讓開發變得更簡單。 前言 RageFrame項目創建于2016年4月16日,基于Yii2框架開發的應用開發引擎,目前正在成長中,目的是為了集成更多...
摘要:目的分析通過實戰,分享多模型與事務的簡單用法。多模型驗證數據全部通過后才能保存數據,否則保存失敗事務保存數據遇到異常會把原來已保存的數據撤銷。多模型表與表之間無聯系,事務表與表之間要有聯系。相關資料多模型的復合表單事務事務什么情況使用 前言 Yii2的多模型與事務平時用的也挺多的,但是網上現有的資源不多,為此我覺得有必要做個總結與分享,雷鋒同志的一貫作風,不做解釋。在利用大伙喝咖啡的時...
摘要:目的分析通過實戰,分享多模型與事務的簡單用法。多模型驗證數據全部通過后才能保存數據,否則保存失敗事務保存數據遇到異常會把原來已保存的數據撤銷。多模型表與表之間無聯系,事務表與表之間要有聯系。相關資料多模型的復合表單事務事務什么情況使用 前言 Yii2的多模型與事務平時用的也挺多的,但是網上現有的資源不多,為此我覺得有必要做個總結與分享,雷鋒同志的一貫作風,不做解釋。在利用大伙喝咖啡的時...
摘要:下面圍繞的這樣的目的,即左右知乎網頁上屏幕截圖功能的實現前端掘金背景最近注意到知乎的屏幕截圖反饋功能,感覺非常不錯。正如你期望的,文中的闖關記之垃圾回收和內存管理前端掘金題圖來源,授權基于協議。 微信小程序實戰學習 起手式 DEMO 仿肯德基 - 前端 - 掘金小程序?大場景? 微信小程序本質上來說就是一個 HTML 5(移動網頁) 應用,用view、scoll-view代替了div標...
閱讀 472·2023-04-25 17:26
閱讀 1495·2021-08-05 09:58
閱讀 1959·2019-08-30 13:17
閱讀 944·2019-08-28 17:52
閱讀 1061·2019-08-26 18:27
閱讀 1413·2019-08-26 14:05
閱讀 3608·2019-08-26 14:05
閱讀 1586·2019-08-26 10:45