[英]Asynchronous method containing Stored Procedure
在我的控制器中, [POST]
方法通常從數據庫調用存儲過程。 我想知道我是否在做正確的事情以避免並發問題。 以下面的方法為例:
[HttpPost]
public async Task<IActionResult> Create(Phase phase)
{
int releaseId = (int)TempData["id"];
string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
string sql = "CreatePhase";
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.CommandType = CommandType.StoredProcedure;
// adding parameters
SqlParameter parameter = new SqlParameter
{
ParameterName = "@Name",
Value = phase.Name,
SqlDbType = SqlDbType.VarChar,
Size = 50
};
command.Parameters.Add(parameter);
parameter = new SqlParameter
{
ParameterName = "@ReleaseId",
Value = releaseId,
SqlDbType = SqlDbType.Int
};
command.Parameters.Add(parameter);
connection.Open();
await command.ExecuteNonQueryAsync();
connection.Close();
}
}
return RedirectToAction("Index", "Phase", new { id = releaseId });
}
是await command.ExecuteNonQueryAsync();
避免並發的正確方法? 它有什么作用嗎? 有沒有更好的方法來實現這一目標,或者這是否足夠好?
異步與並發無關。 事實上,如果有的話,它會增加並發問題,因為異步操作沒有定義的順序,因此是“異步的”。 但是,在像 Web 應用程序這樣的多線程環境中,並發性是一個問題,無論是同步還是異步,因為 1000 個左右的線程中的每一個都可以同時執行相同的工作。
處理並發只有兩種真正的方法:鎖和並發令牌。 並發令牌是最好的方法,但它們只適用於現有的東西(而不是插入)。 基本上,您有一列存儲並發令牌,每次在該行上進行操作時,都會更新令牌。 然后,在您實際執行操作之前,您檢查令牌是否與您首先獲得該行時相同(意味着沒有任何更改)。 如果是這樣,那么您可以繼續操作。 如果沒有,那么其他東西已經修改了它,因此,繼續下去不再安全。 此檢查是通過 where 子句完成的。 例如:
update Foos set Bar = 'Baz' where Id = 1 and Version = {token}
如果Version
的令牌不再相同,那么顯然沒有行將匹配並且沒有任何更新。 然后您可以使用返回的操作計數(即零)來確定存在並發故障並恢復。
這不適用於插入,因為沒有任何東西可以確定是否發生了更改。 (您不能在插入中使用 where 子句。)對於這種情況,您別無選擇,只能使用鎖來防止在執行操作時發生任何其他事情。 但是,鎖絕對會扼殺您的吞吐量,因為它本質上會強制后續請求排隊,並且一次只能處理一個。 因此,當並發是一個問題時,您應該完全避免這些類型的操作。 (不相互沖突的插入是好的。)
首先,異步不是並發或多線程,而是提高了吞吐量。 你是想解決並發還是吞吐量? 吞吐量意味着許多請求調用該進程而無需等待另一個請求完成。 並發意味着讓多個工作線程(線程)並發運行以完成一個進程。 查看您的示例,您不需要多個線程,因為該進程不受處理器限制但 I/O 受限制,因此單線程異步操作就可以了
如果你希望你的代碼是異步的“await command.ExecuteNonQueryAsync();” 正確,因為您正在執行 I/O 操作,並且在 I/O 操作完成之前它不會保留線程。 一旦它點擊“await command.ExecuteNonQueryAsync();” 它會將線程釋放給調用者,一旦操作完成,它就會返回之前執行的線程的控制權。
請在這里找到一個很好的答案,
異步編程和多線程有什么區別? 和一篇優秀的文章https://exceptionnotfound.net/async-await-in-asp-net-csharp-ultimate-guide/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.