FreeSql實現了四種數據庫事務的使用方法,臟讀等事務相關方法暫時未提供。主要原因系這些方法各大數據庫、甚至引擎的事務級別五花八門較難統一。
事務用于處理數據的一致性,處于同一個事務中的操作是一個UnitOfWork,要么全部執行成功,要么全部執行失敗。
指定事務對象
FreeSql 提供了指定事務對象的方法,將事務對象暴露給外部;
orm.Update<xxx>().WithTransaction(指定事務).Set(a => a.Clicks + 1).ExecuteAffrows();
ISelect、IInsert、IUpdate、IDelete,都支持 WithTransaction 方法。
同線程事務
假設用戶購買了價值100元的商品:
第一步:扣余額;
第二步:扣庫存;
第一步成功了,到了第二步發現庫存不足時,事務可以回滾,扣余額的數據將不生效。
//假設已經有了其他wiki頁的IFreeSql聲明
fsql.Transaction(() => {var affrows = fsql.Update<User>().Set(a => a.Wealth - 100).Where(a => a.Wealth >= 100)//判斷別讓用戶余額扣成負數.ExecuteAffrows();if (affrows < 1) {throw new Exception("用戶余額不足");//拋出異常,事務退出}affrows = fsql.Update<Goods>().Set(a => a.Stock - 1).Where(a => a.Stock > 0)//判斷別讓用庫存扣成負數.ExecuteAffrows();if (affrows < 1) {throw new Exception("商品庫存不足");//拋出異常,回滾事務,事務退出//用戶余額的扣除將不生效}//程序執行在此處,說明都扣成功了,事務完成并提交
});
注意與說明:
1、數據庫事務在線程掛載,每個線程只可開啟一個事務連接,重復開啟會獲取線程已開啟的事務;
2、在事務代碼過程中,不可使用異步方法,包括FreeSql提供的數據庫異步方法,否則線程將會切換事務不生效;
3、fsql.Transaction 有防止死鎖機制,60秒事務未結束的,將會被其他線程強行提交(不是回滾),可能造成不完整的事務,但仔細一想60秒還沒完成的事務是什么原因呢?如果嫌60秒太少了可以在重載方法的參數中設置;
后續我們將介紹倉儲模式下的工作單元,和 DbContext 事務使用。
系列文章導航
(一)入門
(二)自動遷移實體
(三)實體特性
(四)實體特性 Fluent Api
(五)插入數據
(六)批量插入數據
(七)插入數據時忽略列
(八)插入數據時指定列
(九)刪除數據
(十)更新數據
(十一)更新數據 Where
(十二)更新數據時指定列
(十三)更新數據時忽略列
(十四)批量更新數據
(十五)查詢數據
(十六)分頁查詢
(十七)聯表查詢
(十八)導航屬性
(十九)多表查詢
(二十)多表查詢 WhereCascade
(二十一)查詢返回數據
(二十二)Dto 映射查詢
(二十三)分組、聚合
(二十四)Linq To Sql 語法使用介紹
(二十五)延時加載
(二十六)貪婪加載 Include、IncludeMany、Dto、ToList
(二十七)將已寫好的 SQL 語句,與實體類映射進行二次查詢
(二十八)事務
(二十九)Lambda 表達式
(三十)讀寫分離
(三十一)分區分表
(三十二)Aop
(三十三)CodeFirst 類型映射
(三十四)CodeFirst 遷移說明
(三十五)CodeFirst 自定義特性