[英]How to send email and roll back changes?
我正在為asp.net MVC中的用戶創建投訴注冊表。 投訴發送到用戶的電子郵件地址,投訴保存到SQL Server 2017數據庫中。 我需要一個建議。 我的問題是,我如何處理電子郵件和數據庫?
條件1 - 如果數據庫無法保存數據但電子郵件正在發送,該怎么辦?
條件2 - 如果數據庫將數據保存到表但無法發送電子郵件,該怎么辦?
我是怎么做的
public void MyFunction()
{
try {
var db = DbContext();
//some code
//The number of state entries written to database
int entities = db.SaveChanges();
if (entities > 0)
{
SendEmail();//what fails to send email and complaint is created.
}
}
catch(Exception ex)
{
//exception is handle
}
}
db.SaveChanges()
完成后,它將返回寫入數據庫的表數。 從我的作業來看,第二個條件是最重要的。
我想要的結果是,創建和發送電子郵件的過程都順利處理。
我是走在正確的道路上嗎?
任何建議表示贊賞。
在這種情況下,我要做的是將電子郵件保存到數據庫中的表中,並實現從該表讀取的服務,並發送任何未發送的電子郵件,並為每個條目重試計數。
這樣,如果失敗,您可以隨時重試發送電子郵件。
在現實生活中,您將嘗試將電子郵件進程處理到另一個服務(如sendgrind),因此您的應用程序將存儲保存完成后發送電子郵件的請求。 只要有可能,您的服務就會處理此請求; 此外,您無需等待發送電子郵件以完成用戶的請求。
既然你正在做作業,你可以:
1- [推薦]將該電子郵件存儲在一個表中並從中獲取一個小服務,一旦找到記錄,發送電子郵件並標記為已done
。
2- [不喜歡]完全像你那樣做。 保存記錄,如果success
發送電子郵件。
這是一個有趣的問題,因為它要求你考慮權衡,概率和完美與足夠好的東西。
這就是足夠好的:更新數據庫。 如果成功,則將消息放入隊列(可能是另一個數據庫表)中,這將導致發送電子郵件。
您可以在數據庫更新時直接通過SMTP發送電子郵件,但由於某些奇怪的瞬態條件,電子郵件將無法發送,因此很可能。 (這種情況發生 - 也許SMTP權限搞砸了,電子郵件被拒絕了。)將它放在一個單獨進程的隊列中是一種合理的方法,可以確保您的電子郵件具有一定的彈性。
為什么那只“足夠好”? 因為沒有什么是防彈的。 您的電子郵件仍有可能無法發送。 畢竟,我們擔心數據庫更新可能會失敗。 但是,如果我們通過將記錄插入另一個其他進程監視的數據庫來發送電子郵件,那是不是意味着也可能失敗? 如果第一次數據庫更新成功但發送電子郵件的人失敗,我們會怎么做?
這就是我們開始權衡利弊的地方。 我們可能會將投訴插入數據庫但不會發送電子郵件。 這有多大可能,如果發生,有多糟糕? 無論我們考慮采取什么措施來應對這種不太可能的情況,這也不會失敗嗎?
那是一個兔子洞。 我們可以無休止地使我們的代碼變得越來越復雜,試圖考慮越來越不可能的場景,但它不值得。 最終我們過於復雜的代碼中的錯誤將成為某些東西無效的原因。
而不是追逐它,更有意義的是,有時我們的代碼會因為我們無法控制的事情而失敗,並且知道失敗會是什么樣子。 同樣,這是一個什么是好的問題。
即使這樣也會失敗。 我們的日志記錄和警報可能會失敗。 我們可以用更具彈性的東西替換它們,比如更好的消息隊列。 但是,當不可能時,我們可能會瘋狂地試圖解釋所有事情。 我們所能做的就是盡量使我們的應用程序可靠和有彈性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.