博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NopCommerce添加事务机制
阅读量:6218 次
发布时间:2019-06-21

本文共 3444 字,大约阅读时间需要 11 分钟。

NopCommerce,一直没有事务机制。作为一个商城,我觉得事务也还是很有必要的。以下事务代码以3.9版本作为参考:

首先,IDbContext接口继承IDisposable接口,以便手动释放相关资源,并添加一个新方法CurrentEntries,目的是得到跟踪实体的当前跟踪状态(主要作用是使用事务回滚后改变当前实体对应的状态):

///         /// 得到跟踪实体的当前跟踪状态        ///  /// 
IEnumerable
CurrentEntries();

自然相应的IDbContext接口实现类NopObjectContext也要实现该方 CurrentEntries() { return ChangeTracker.Entries(); }

注意:主项目代码添加这个方法之后,所有需要操作数据库的插件都要实现该方法,这个大家自行斟酌,如果插件也需要事务的话。

添加一个接口命名IUnitOfWork,如下:

 

public interface IUnitOfWork : IDisposable    {        ///         /// 开启事务 ///  ///  void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified); ///  /// 提交 ///  void Commit(); ///  /// 回滚 ///  void Rollback(); ///  /// 释放资源 ///  /// 是否释放 void Dispose(bool disposing); }

 

并实现该接口,添加实现类命名UnitOfWork,如下:

public class UnitOfWork : IUnitOfWork    {        private IDbContext _context;        private ObjectContext _objectContext; private IDbTransaction _transaction; private bool _disposed; public UnitOfWork(IDbContext context) { _context = context; } public void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified) { _objectContext = ((IObjectContextAdapter)_context).ObjectContext; if (_objectContext.Connection.State != ConnectionState.Open) _objectContext.Connection.Open(); _transaction = _objectContext.Connection.BeginTransaction(isolationLevel); } public void Commit() { _transaction.Commit(); } public void Rollback() { _transaction.Rollback(); foreach (var entry in _context.CurrentEntries()) { switch (entry.State) { case EntityState.Modified: entry.State = EntityState.Unchanged; break; case EntityState.Added: entry.State = EntityState.Detached; break; case EntityState.Deleted: entry.State = EntityState.Unchanged; break; } } } public void Dispose(bool disposing) { if (_disposed) return; if (disposing) { try { if (_objectContext != null && _objectContext.Connection.State == ConnectionState.Open) _objectContext.Connection.Close(); } catch (ObjectDisposedException) { } if (_context != null) { _context.Dispose(); _context = null; } } _disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } }

代码很好理解,我就不多做注释了,不清楚的自行网上了解。

下面附上我写的单元测试:

[TestClass]    public class UnitTest1    {        protected static NopObjectContext Context = new NopObjectContext(ConfigurationManager.ConnectionStrings["ConnectionStr"].ToString()); private readonly IUnitOfWork _unitOfWork = new UnitOfWork(Context); protected readonly IRepository
ForumGroupRepository = new EfRepository
(Context); protected readonly IRepository
SettingRepository = new EfRepository
(Context); [TestMethod] public void Can_Commit_Test() { try { _unitOfWork.BeginTransaction(); // 开启事务 var forumGroup = new ForumGroup { Name = "ForumGroup1", // 自行建立Name的唯一约束测试,测试两次第二次会自行回滚 DisplayOrder = 1, CreatedOnUtc = DateTime.Now, UpdatedOnUtc = DateTime.Now.AddDays(1) }; ForumGroupRepository.Insert(forumGroup); // 第一次插入数据 var setting = new Setting { Name = "test_transaction_name", Value = "test_transaction_value", StoreId = 1 }; SettingRepository.Insert(setting); _unitOfWork.Commit(); // 提交 } catch (Exception) { _unitOfWork.Rollback(); // 回滚 } Assert.AreEqual(ForumGroupRepository.TableNoTracking.Count(), 1); Assert.AreEqual(SettingRepository.TableNoTracking.Count(x => x.Name == "test_transaction_name"), 1); } }

转载于:https://www.cnblogs.com/zhangruisoldier/p/7988619.html

你可能感兴趣的文章
我的友情链接
查看>>
我的友情链接
查看>>
linux svn 客户端安装配置
查看>>
RedHat Enterprise linux 4-6 下载连接汇总
查看>>
主席树K-th Number
查看>>
源码包安装vsftp及相关配置
查看>>
认识/dev/shm
查看>>
SWFTools pdf2swf 参数详解 及中文乱码问题
查看>>
Apache 用户验证
查看>>
你用pig分析access_log日志中ip访问次数
查看>>
Linux上的GPG简单应用
查看>>
Python 的路数
查看>>
福建省漳州市医院信息系统备份归档容灾系统采购项目
查看>>
如何获取InnoDB树的高度
查看>>
前端面试试题
查看>>
F5加入OpenStack社区 推动4-7层网络服务演进
查看>>
洛谷——P1238 走迷宫
查看>>
我的友情链接
查看>>
Linux常用命令--paste
查看>>
kubernetes+docker 基础架构搭建使用
查看>>