EF6學習筆記二十四:事務
阿新 • • 發佈:2019-01-30
lba security laptop date 簡單的 nbsp sed als 詳細
要專業系統地學習EF推薦《你必須掌握的Entity Framework 6.x與Core 2.0》。這本書作者(汪鵬,Jeffcky)的博客:https://www.cnblogs.com/CreateMyself/
了解一下EF中事務。首先復習一下原始的SQL語句創建事務,然後也復習一下ADO中事務的使用。工作一年多我就沒寫過事務,因為用的是EF,事務就只是在學校中寫過。
詳細學習事務:https://www.cnblogs.com/knowledgesea/p/3714417.html
begin transaction begin try insert into tb_Students valuesView Code(newid(),‘小明‘,‘44‘,‘2012-1-1‘); insert into tb_Teachers values(newid(),‘張四海‘,‘語文‘,‘2018-2-2‘); end try begin catch select ERROR_NUMBER() as ErrorNumber, -- 錯誤代碼 ERROR_SEVERITY() as ErrorSeverity,-- 錯誤嚴重級別,級別小於10,try catch捕獲不到 ERROR_STATE() as ErrorState, -- 錯誤狀態碼ERROR_PROCEDURE() as ErrorProcedure, -- 出現錯誤的存儲過程或觸發器的名稱 ERROR_LINE() as ErrorLine, -- 發生錯誤的行號 ERROR_MESSAGE() as ErrorMessage -- 錯誤的具體信息 if(@@TRANCOUNT > 0) -- 事務開啟此值+1,判斷是否開啟事務 rollback transaction end catch if(@@TRANCOUNT >0) commit tran
// ado中使用事務 string connStr = @"Data Source=LAPTOP-G81QJ856\SQLEXPRESS;Initial Catalog=_20190130.EFDbContext;Integrated Security=True"; using (SqlConnection conn = new SqlConnection(connStr)) { Console.WriteLine(conn.State); // closed 我還以為使用using自動打開的 conn.Open(); string sql = @"insert into tb_Students values(newid(),‘小強‘,‘44‘,‘2012-1-1‘);insert into tb_Teachers values(newid(),‘張拋‘,‘數學‘,‘1999-9-2‘);"; using (SqlCommand cmd = new SqlCommand(sql, conn)) { using (SqlTransaction tran = conn.BeginTransaction()) { try { // 如果不告訴cmd使用哪個事務會報錯 //// System.InvalidOperationException: 如果分配給命令的連接位於本地掛起事務中,ExecuteNonQuery 要求命令擁有 事務。命令的 Transaction 屬性尚未初始化。 cmd.Transaction = tran; var i = cmd.ExecuteNonQuery(); tran.Commit(); } catch (Exception e) { tran.Rollback(); throw e; } } } }View Code
現在來看看EF中事務是怎麽回事
我們平時在執行添加、修改、刪除調用SaveChanges方法時,就會被默認的被事務包裹。查詢沒有
ctx.Students.Add(new Student { Name = "小劉", Score = "55", AddTime = DateTime.Now });View Code
當我們多次調用SaveChanges時,就會開啟多個事務。
ctx.Students.Add(new Student { Name="小新",Score="66"}); ctx.SaveChanges(); ctx.Teachers.Add(new Teacher { Name="胡飄",Subject="歷史"}); ctx.SaveChanges();View Code
現在來看EF中的一個關於事務的配置
public class EFDbContext : DbContext { public EFDbContext() { //此標誌確定在使用此類方法時是否啟動新事務 Configuration.EnsureTransactionsForFunctionsAndCommands = false; } }View Code
這個就是開啟關閉事務的開關,但是他對SaveChanges是不起作用的,目前我只知道調用ExecuteSqlCommand方式時才有用。MSDN上對這個都說的很簡陋
那麽看看EF中對這個屬性的註釋
還是直接來看看,下面這條語句我關閉事務, 添加一條記錄,然後調用SaveChanges,但其實,還是會開啟事務
// 還是會有事務的 ctx.Configuration.EnsureTransactionsForFunctionsAndCommands = false; ctx.Database.Log = msg => Console.WriteLine(msg); ctx.Teachers.Add(new Teacher { Name = "胡憤", Subject = "歷史" }); ctx.Students.Add(new Student { Name = "小趙", Score = "66", AddTime = DateTime.MinValue }); ctx.SaveChanges();View Code
ExecuteSqlCommand也是默認被事務包裹,但是他就可以通過傳遞參數來實現事務的開啟和關閉。
ctx.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, @"insert into tb_students values(newid(),‘小劉‘,‘70‘,getdate())");View Code
行吧,就是這樣。
如果說我們想用ADO中那種方式來使用事務呢?當然是可以的,上下文提供了BeginTransaction,和ADO中的命名是一樣的。
using (var transaction = ctx.Database.BeginTransaction()) { ctx.Teachers.Add(new Teacher { Name = "胡憤", Subject = "歷史" }); ctx.SaveChanges(); ctx.Students.Add(new Student { Name = "小趙", Score = "66", AddTime = DateTime.Now }); ctx.SaveChanges(); transaction.Commit(); }View Code
我雖然調用了兩次saveChanges,但只有一個事務,但是必須要調用一次SaveChanges才能成功插入
最後開看一下EF提供的UseTransaction方法,這個是什麽意思呢?允許上下文參與到已存在的事務中。
我們現在使用ADO,將ADO的transaction對象傳遞給EF的UseTransaction,那麽我在ADO中的操作和在EF中的操作就可以處在同一個事務中
string connStr = @"Data Source=LAPTOP-G81QJ856\SQLEXPRESS;Initial Catalog=_20190130.EFDbContext;Integrated Security=True"; using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); string sql = @"insert into tb_students values(newid(),‘小藍 ‘,‘70‘,getdate())"; using (SqlCommand cmd = new SqlCommand(sql, conn)) { using (SqlTransaction tran = conn.BeginTransaction()) { try { cmd.Transaction = tran; var i = cmd.ExecuteNonQuery(); using (EFDbContext ctx = new EFDbContext(conn)) { ctx.Database.UseTransaction(tran); ctx.Students.Add(new Student { Name = "小紅", Score = "55", AddTime = DateTime.Now }); ctx.SaveChanges(); } tran.Commit(); } catch (Exception e) { tran.Rollback(); throw e; } } } }View Code
行吧,EF中簡單的事務就到這裏了。
EF6學習筆記二十四:事務