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. new 、 delete 、 malloc 、 free 关系

    1.new . delete . malloc . free 关系 delete 会调用对象的析构函数 , 和 new 对应, free 只会释放内存, new 调用构造函数. malloc 与 fr ...

  2. Servlet与JSP内置对象的对应关系、Servlet获取表单、Servlet路径跳转

    项目的根目录指的是webroot: 服务器内部跳转: 或者使用../:“..”代表回到上一级目录

  3. jmeter系列-------脚本编写格式

    1.通常会将用户和服务器的一次交互(页面访问或者提交)请求放在一个简单控制器或者事务控制器,例如微课首页里面包含4个接口都放到简单控制器里 或者一个提交可能,会触发3个接口,那么这3个接口放到一个简单 ...

  4. MongoDB-python的API手记

    -------------------python调用MongoDB------------------- 1.官方文档:http://api.mongodb.org/python/current/t ...

  5. 初学者入门web前端:C#基础知识:函数

    入行前端对函数的掌握程度有可能直接影响以后工作的效率,使用函数可以高效的编写编码,节省时间,所以我整理了C#中最基础的函数知识点,虽然我在学习中 遇到很多问题,但是只要能够解决这些问题,都是好的. 一 ...

  6. jQuery中getJSON跨域原理详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp28 jQuery中getJSON跨域原理详解 前几天我再开发一个叫 河蟹工 ...

  7. jQuery === 面条式代码?

    自从React/Vue等框架流行之后,jQuery被打上了面条式代码的标签,甚至成了"过街老鼠",好像谁还在用jQuery,谁就还活在旧时代,很多人都争先恐后地拥抱新框架,各大博客 ...

  8. Java基础学习——泛型

    一.泛型方法 /** 自定义泛型:自定义泛型可以理解为是一个数据类型的占位符,或者理解为是一个数据类型的变量. 泛型方法: 泛型方法的自定义格式:修饰符<声明自定义泛型>返回值类型 函数名 ...

  9. Calico 的网络结构是什么?- 每天5分钟玩转 Docker 容器技术(68)

    上一节我们部署了 Calico 网络,今天将运行容器并分析 Calico 的网络结构. 在 host1 中运行容器 bbox1 并连接到 cal_net1: docker container run ...

  10. linux模拟实现主机跨路由通信

    p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; f ...