FreeSql (二十八)事務

FreeSql實現了四種數據庫事務的使用方法,髒讀等事務相關方法暫時未提供。主要緣由系這些方法各大數據庫、甚至引擎的事務級別五花八門較難統一。html

事務用於處理數據的一致性,處於同一個事務中的操做是一個UnitOfWork,要麼所有執行成功,要麼所有執行失敗。sql

指定事務對象

FreeSql 提供了指定事務對象的方法,將事務對象暴露給外部;數據庫

orm.Update<xxx>().WithTransaction(指定事務)
    .Set(a => a.Clicks + 1).ExecuteAffrows();

ISelect、IInsert、IUpdate、IDelete,都支持 WithTransaction 方法。異步

同線程事務

假設用戶購買了價值100元的商品:大數據

第一步:扣餘額;線程

第二步:扣庫存;code

第一步成功了,到了第二步發現庫存不足時,事務能夠回滾,扣餘額的數據將不生效。orm

//假設已經有了其餘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("商品庫存不足");
        //拋出異常,回滾事務,事務退出
        //用戶餘額的扣除將不生效
    }

    //程序執行在此處,說明都扣成功了,事務完成並提交
});

注意與說明:htm

一、數據庫事務在線程掛載,每一個線程只可開啓一個事務鏈接,重複開啓會獲取線程已開啓的事務;對象

二、在事務代碼過程當中,不可以使用異步方法,包括FreeSql提供的數據庫異步方法,不然線程將會切換事務不生效;

三、fsql.Transaction 有防止死鎖機制,60秒事務未結束的,將會被其餘線程強行提交(不是回滾),可能形成不完整的事務,但仔細一想60秒還沒完成的事務是什麼緣由呢?若是嫌60秒太少了能夠在重載方法的參數中設置;

後續咱們將介紹倉儲模式下的工做單元,和 DbContext 事務使用。

系列文章導航

相關文章
相關標籤/搜索