国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Winform開發框架里面使用事務操作的原理及介紹

2019-11-17 03:12:02
字體:
來源:轉載
供稿:網友

Winform開發框架里面使用事務操作的原理及介紹

在很多情況下,事務是個很有用的東西,可以把一系列的操作組合成一個原子粒度的操作,一旦組合中某個地方出錯,可以整個干凈的進行滾回,不會留下臟數據;除此之外,事務還能提高批量操作的效率,如在本地SQLite數據庫里面,批量插入1萬條數據,那么使用事務和沒有使用事務,速度上至少差別幾十到上百倍的差異。既然事務有完整性和速度性的差異,因此,基于上述原因,我們在很多情況下最好使用事務進行操作。本文主要介紹在開發框架中如何整合事務的操作,并介紹在各個分層中的事務使用案例。

由于我介紹的相關框架,主要是采用了微軟的EnterPRise Library的數據庫訪問模塊,因此它能夠很好抽象各種數據庫的事務,以適應各種不同數據庫的事務處理。使用微軟的Enterprise Library模塊,可以很好支持SQLSever、OracleMySQLaccess、SQLite等數據庫。

1、數據訪問層中的事務操作

1.1 數據訪問層的事務接口定義

由于使用事務操作,因此在底層的模塊里面,也就是這里的數據訪問層,一般需要一個事務對象的參數。如下代碼是一個數據訪問層的接口定義。

    /// <summary>    /// 數據訪問層的接口    /// </summary>    public interface IBaseDAL<T> where T : BaseEntity    {        /// <summary>        /// 插入指定對象到數據庫中        /// </summary>        /// <param name="obj">指定的對象</param>        /// <param name="trans">事務對象</param>        /// <returns>執行成功返回True</returns>        bool Insert(T obj, DbTransaction trans = null);                /// <summary>        /// 根據指定對象的ID,從數據庫中刪除指定對象        /// </summary>        /// <param name="key">指定對象的ID</param>        /// <param name="trans">事務對象</param>        /// <returns>執行成功返回<c>true</c>,否則為<c>false</c>。</returns>        bool Delete(object key, DbTransaction trans = null);                /// <summary>        /// 更新對象屬性到數據庫中        /// </summary>        /// <param name="obj">指定的對象</param>        /// <param name="primaryKeyValue">主鍵的值</param>        /// <param name="trans">事務對象</param>        /// <returns>執行成功返回<c>true</c>,否則為<c>false</c>。</returns>        bool Update(T obj, object primaryKeyValue, DbTransaction trans = null);                /// <summary>        /// 查詢數據庫,檢查是否存在指定ID的對象        /// </summary>        /// <param name="key">對象的ID值</param>        /// <param name="trans">事務對象</param>        /// <returns>存在則返回指定的對象,否則返回Null</returns>        T FindByID(object key, DbTransaction trans = null);                        .....................//其他操作            }

從上面的代碼上,我們可以看到,里面的增刪改查等操作,最后都帶一個trans的事務對象參數,這個參數默認為null,也就是可選參數的做法,這個方法就提供了兩個重載的方法供我們使用。

看到這里,可能有些人提出疑問,為什么查找方法也傳入事務對象,這個因為事務是一個排斥性操作,一旦啟動了事務,可能這個表的其他操作會被鎖定,但在這個事務內操作確實可以允許的,如果你使用SQLite這種單機版的數據庫,在一個地方采用事務操作一個表,在事務內部接著不使用事務進行表的任何操作將不會被允許,數據庫提示出錯信息的。

基于這個原因,所有表操作的接口,都應該提供事務性的操作接口,也就是提供一個事務性的對象參數。在接口的實現里面,判斷事務對象是否為空,然后進行相應的處理即可。

1.2 在DAL層自定義函數的事務操作

由于在IBaseDAL里面已經定義了很多事務性的接口,因此數據訪問層的基類里面也已經實現了很多相關的基礎操作。

因此數據訪問層DAL層里面,如自己定義的實現函數,調用這些基礎函數進行處理就可以了。自定義函數對事務的操作處理,代碼如下所示。

        /// <summary>        /// 調整客戶的組別        /// </summary>        /// <param name="customerId">客戶ID</param>        /// <param name="groupIdList">客戶分組Id集合</param>        /// <returns></returns>        public bool ModifyCustomerGroup(string customerId, List<string> groupIdList)        {            bool result = false;            DbTransaction trans = base.CreateTransaction();            if (trans != null)            {                string sql = string.Format("Delete from T_CRM_CustomerGroup_Customer where Customer_ID='{0}' ", customerId);                base.SqlExecute(sql, trans);                foreach (string groupId in groupIdList)                {                    sql = string.Format("Insert into T_CRM_CustomerGroup_Customer(Customer_ID,CustomerGroup_ID) values('{0}', '{1}') ", customerId, groupId);                    base.SqlExecute(sql, trans);                }                try                {                    trans.Commit();                    result = true;                }                catch                {                    trans.Rollback();                    throw;                }            }            return result;        }

2、業務邏輯層的事務操作

業務邏輯層BLL層是對數據訪問層的更高一層的封裝,它也相應提供相應的事務對象接口,以方便外部的調用。

它的業務類里面,自定義函數對事務的調用操作如下所示。

        /// <summary>        /// 把報價單轉換為銷售訂單        /// </summary>        /// <param name="quotationNo">報價單編號</param>        /// <returns></returns>        public bool ConvertToOrder(string orderNo, int userId)        {            bool result = false;            DbTransaction trans = baseDal.CreateTransaction();            if (trans != null)            {                SellInfo sellInfo = ConvertSellInfo(orderNo, userId, trans);                List<OrderDetailInfo> detailList = new List<OrderDetailInfo>();                if (sellInfo != null)                {                    detailList = ConvertOrderDetal(sellInfo, orderNo, trans);                }                bool success = BLLFactory<Sell>.Instance.Insert(sellInfo, trans);                if (success)                {                    foreach (OrderDetailInfo info in detailList)                    {                        BLLFactory<OrderDetail>.Instance.Insert(info, trans);                    }                                    }                try                {                    trans.Commit();                    result = true;                }                catch                {                    trans.Rollback();                    throw;//重新拋出異常                }            }            return result;        }

另一例子如下所示。

        /// <summary>        /// 刪除報價單及明細信息        /// </summary>        /// <param name="id"></param>        /// <returns></returns>        public bool DeleteQuotationRelated(string id)        {            bool result = false;            DbTransaction trans = CreateTransaction();            if (trans != null)            {                QuotationInfo info = baseDal.FindByID(id, trans);                if (info != null)                {                    List<QuotationDetailInfo> detailList = BLLFactory<QuotationDetail>.Instance.FindByOrderNo(info.HandNo, trans);                    foreach (QuotationDetailInfo detailInfo in detailList)                    {                        BLLFactory<QuotationDetail>.Instance.Delete(detailInfo.ID, trans);                    }                    //最后刪除主表訂單數據                    baseDal.Delete(id, trans);                    try                    {                        trans.Commit();                        result = true;                    }                    catch (Exception ex)                    {                        trans.Rollback();                        LogTextHelper.Error(ex);                        throw;                    }                }            }            return result;        }    }

3、Winform界面層對事務的調用

由于Winform界面層,直接調用BLL層的相應接口,進行數據的操作的,因此我們也可以在界面層創建相應的事務對象,然后在界面層操作事務。

界面層調用事務處理,操作代碼如下所示。

            using (DbTransaction trans = BLLFactory<Function>.Instance.CreateTransaction())            {                try                {                    if (trans != null)                    {                        bool sucess = BLLFactory<Function>.Instance.Insert(mainInfo, trans);                        if (sucess)                        {                            FunctionInfo subInfo = null;                            int sortCodeIndex = 1;                            #region 子功能操作                            if (chkAdd.Checked)                            {                                subInfo = CreateSubFunction(mainInfo);                                subInfo.SortCode = (sortCodeIndex++).ToString("D2");                                subInfo.ControlID = string.Format("{0}/Add", mainInfo.ControlID);                                subInfo.Name = string.Format("添加{0}", mainInfo.Name);                                BLLFactory<Function>.Instance.Insert(subInfo, trans);                            }                            if (chkDelete.Checked)                            {                                subInfo = CreateSubFunction(mainInfo);                                subInfo.SortCode = (sortCodeIndex++).ToStr
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 丰宁| 华亭县| 皋兰县| 崇礼县| 呼玛县| 确山县| 青田县| 仁怀市| 任丘市| 甘德县| 龙游县| 周至县| 梁河县| 华池县| 阜平县| 安阳市| 安龙县| 江口县| 宿州市| 余江县| 山阴县| 南宫市| 墨脱县| 平和县| 瑞金市| 民勤县| 辉南县| 尼玛县| 白玉县| 阳春市| 乾安县| 贵港市| 刚察县| 景宁| 宁德市| 嘉定区| 定结县| 三门县| 资兴市| 金湖县| 盐亭县|