[.NET][EF]利用transaction進行多個entity的savechanges

  • 5976
  • 0
  • 2019-10-08

[.NET][EF]利用transaction進行多個entity的savechanges

方法1:利用transactionscope進行多個entity的savechanges
ps2019/10/08.現在越來越多客戶不願意把伺服器的分散式交易(MSDTC)的設定開放,將會導致transactionscope無法正常運作而出現(基礎提供者open  失敗)的錯誤訊息,因此微軟漸漸的轉而使用下面的第二個方法BeginTransaction(),包含現在正在推的.NET core也都建議改用BeginTransaction()

private void btnTransactionScope_Click(object sender, EventArgs e)
{
	using (TransactionScope ts = new TransactionScope())
	{
		using (DB1Entities db1 = new DB1Entities())
		{
			db1.Parameter.Add(new Parameter() {
				 Name = "test111", 
				 Value = "value111",
				  Description = "none111",
				   Status = true
			});
			db1.SaveChanges();
		}
		using (DB2Entities db2 = new DB2Entities())
		{
			db2.Parameter.Add(new Parameter()
			{
				Name = "test222",
				Value = "value22",
				Description = "none222",
				Status = true
			});
			db2.SaveChanges();
		}

		ts.Complete();
	}
	
}


補充:
如何在開發階段,加長transaction scope的時間。下面示範加長時間為20分鐘,下中斷點的時候,常常需要多點時間分析。
正式上線的時候這段不要加入到config檔案就好

<configuration>
	<system.transactions>
		<defaultSettings timeout="00:20:00" />
	</system.transactions>
</configuration>


方法2:利用BeginTransaction()
 

private void btnTestBeginTransaction_Click(object sender, EventArgs e)
{
	using (DB1Entities db1 = new DB1Entities())
	{
		using (DB2Entities db2 = new DB2Entities())
		{
			using (var transaction1 = db1.Database.BeginTransaction())
			{

				using (var transaction2 = db2.Database.BeginTransaction())
				{
					db1.Parameter.Add(new Parameter()
					{
						Name = "test1008_data1",
						Value = "value1008_data1",
						Description = "none1008_data1",
						Status = true
					});
					db2.Parameter.Add(new Parameter()
					{
						Name = "test1008_data2",
						Value = "value1008_data2",
						Description = "none1008_data2",
						Status = true
					});

					try
					{
						db1.SaveChanges();
						db2.SaveChanges();
						
						transaction1.Commit();
						transaction2.Commit();
						MessageBox.Show("OK");
					}
					catch (DbUpdateException)
					{
						transaction1.Rollback();
						transaction2.Rollback();
						MessageBox.Show("RollBack");
					}
				}
			}
		}
	}

	
}




參考資料:
可彈性支援Transaction的EF資料異動方法
https://blog.darkthread.net/blog/ef-transaction/
[C#.NET][Entity Framework] DbContextTransaction @ EF6
https://dotblogs.com.tw/yc421206/2014/03/20/144457
C# controlling a transaction across multiple databases
https://stackoverflow.com/questions/22512450/c-sharp-controlling-a-transaction-across-multiple-databases