NopCommerce现在最新版是3.9,不过依然没有事务机制。作为一个商城,我觉得事务也还是很有必要的。以下事务代码以3.9版本作为参考:

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

        /// <summary>
/// 得到跟踪实体的当前跟踪状态
/// </summary>
/// <returns></returns>
IEnumerable<DbEntityEntry> CurrentEntries();

自然相应的IDbContext接口实现类NopObjectContext也要实现该方法:

        public IEnumerable<DbEntityEntry> CurrentEntries()
{
return ChangeTracker.Entries();
}

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

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

    public interface IUnitOfWork : IDisposable
{
/// <summary>
/// 开启事务
/// </summary>
/// <param name="isolationLevel"></param>
void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified); /// <summary>
/// 提交
/// </summary>
void Commit(); /// <summary>
/// 回滚
/// </summary>
void Rollback(); /// <summary>
/// 释放资源
/// </summary>
/// <param name="disposing">是否释放</param>
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<ForumGroup> ForumGroupRepository = new EfRepository<ForumGroup>(Context);
protected readonly IRepository<Setting> SettingRepository = new EfRepository<Setting>(Context); [TestMethod]
public void Can_Commit_Test()
{
try
{
_unitOfWork.BeginTransaction(); // 开启事务 var forumGroup = new ForumGroup
{
Name = "ForumGroup1", // 自行建立Name的唯一约束测试,测试两次第二次会自行回滚
DisplayOrder = ,
CreatedOnUtc = DateTime.Now,
UpdatedOnUtc = DateTime.Now.AddDays()
};
ForumGroupRepository.Insert(forumGroup); // 第一次插入数据 var setting = new Setting
{
Name = "test_transaction_name",
Value = "test_transaction_value",
StoreId =
};
SettingRepository.Insert(setting); _unitOfWork.Commit(); // 提交
}
catch (Exception)
{
_unitOfWork.Rollback(); // 回滚
} Assert.AreEqual(ForumGroupRepository.TableNoTracking.Count(), );
Assert.AreEqual(SettingRepository.TableNoTracking.Count(x => x.Name == "test_transaction_name"), 1);
}
}

如果你觉得对你有帮助,右侧打个赏呗!

Authori:黄仲秋

QQ:875755898

NopCommerce添加事务机制的更多相关文章

  1. EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~续~添加事务机制

    回到目录 上一讲中简单介绍了一个EF环境下通过DbCommand拦截器来实现SQLSERVER的读写分离,只是一个最简单的实现,而如果出现事务情况,还是会有一些问题的,因为在拦截器中我们手动开启了Co ...

  2. sprint test 添加事务回滚机制

    1.原因: 单元测试的时候频繁操作数据库需要修改很多数据,造成不必要的操作,添加事务之后就可以重复对一条数据进行操作,并且在返回结果后进行回滚. 2.解决: 原先继承的是  AbstractJUnit ...

  3. Redis学习笔记~Redis事务机制与Lind.DDD.Repositories.Redis事务机制的实现

    回到目录 Redis本身支持事务,这就是SQL数据库有Transaction一样,而Redis的驱动也支持事务,这在ServiceStack.Redis就有所体现,它也是目前最受业界认可的Redis ...

  4. REDIS 事务机制

    基本事务操作: 任何数据库都必须要保证一种原子执行操作:最基本的原子执行操作肯定是需要提供: 举一个例子来说明: 当对某个Key 做一个统计: 可能不同的Client做它那部分的统计,一段时间后,服务 ...

  5. WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程

    今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制. ...

  6. 一文说清 InnoDB 的事务机制

    我们从一个转账的故事开始. 隔壁小王从美团上找到了一家水饺店,准备中午吃水饺.下单成功,支付20元. 商家这里响了一下:叮叮,您有美团外卖新订单啦,请及时处理.水饺一份,好嘞,下锅. 很快小王吃到外卖 ...

  7. 分享我们项目中基于EF事务机制的架构

    写在前面: 1. 本文中单元测试用到的数据库,在执行测试之前,会被清空,即使用空数据库. 2. 本文中的单元测试都是正确通过的. 要理解EF的事务机制,首先要理解这2个类:TransactionSco ...

  8. springmvc 用注解方式添加事务不生效解决方法

    springmvc 事务注册有很多种方法,在此我只mark 用注解方式添加transaction不生效的解决办法. springmvc 注解方法添加事务步骤: 1.在 spring的 root-con ...

  9. NoSQL生态系统——事务机制,行锁,LSM,缓存多次写操作,RWN

    13.2.4 事务机制 NoSQL系统通常注重性能和扩展性,而非事务机制. 传统的SQL数据库的事务通常都是支持ACID的强事务机制.要保证数据的一致性,通常多个事务是不可能交叉执行的,这样就导致了可 ...

随机推荐

  1. spring boot / cloud (五) 自签SSL证书以及HTTPS

    spring boot / cloud (五) 自签SSL证书以及HTTPS 前言 什么是HTTPS? HTTPS(全称:Hyper Text Transfer Protocol over Secur ...

  2. Notification弹出实现

    Notification的几种基本使用方法,大家肯定都已经烂熟于心,我也不必多说.给一个链接:https://zhuanlan.zhihu.com/p/25841482 接下来我想说的是android ...

  3. Andrew Ng机器学习课程笔记--week6(精度&召回率)

    Advice for applying machine learning 本周主要学习如何提升算法效率,以及如何判断学习算法在什么时候表现的很糟糕和如何debug我们的学习算法.为了让学习算法表现更好 ...

  4. js排序与重组

    前几天同学发给我一个问题,思路想整理一下,也供大家参考.实际上这道题本质就是考察的是去重与排序的问题.好了闲话少说,上题. function input(req){     if(req<=10 ...

  5. ThreadLocal类分析

    首先试想一个场景: 多个线程都要访问数据库,先要获得一个Connection,然后执行一些操作.为了线程安全,如果用synchronized锁定一个Connection对象,那么任何时候,都只有一个线 ...

  6. JavaPOI处理Excel

     java处理excel,心得分享如下,如有不妥或者需要补充的地方,敬请指出,欢迎随时交流 1.加载excel,获得workbook对象 fileTemp = new File(pathOfMExce ...

  7. Selenium 学习笔记(一)

    selenium 学习整理 初学者,如果有不当得地方请指出,非常感谢. 准备事项: 1. Python 安装包 安装Python,并勾选添加环境变量. 安装完成后,打开dos窗口,输入python,看 ...

  8. 深入剖析ConcurrentHashMap二

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt200 我们关注的操作有:get,put,remove 这3个操作.对于哈希表 ...

  9. Rsync for windows

    说到电脑,我真是一屋子都是. 从房间到大厅,就已经有5台.这还没包括服务器. 虽然这5台电脑我最常用的也只是2~3台.其他的不是给朋友们来坐的时候打打游戏.就是给妈妈上网看看报纸. 不过我相信很多朋友 ...

  10. java可访问修饰符

    修饰符 同一个类中 同一个包中 不同包的子类 不提供包的非子类 private √ friendly(省略) √ √ protected √ √ √ public √ √ √ √