NopCommerce添加事务机制
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添加事务机制的更多相关文章
- EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~续~添加事务机制
回到目录 上一讲中简单介绍了一个EF环境下通过DbCommand拦截器来实现SQLSERVER的读写分离,只是一个最简单的实现,而如果出现事务情况,还是会有一些问题的,因为在拦截器中我们手动开启了Co ...
- sprint test 添加事务回滚机制
1.原因: 单元测试的时候频繁操作数据库需要修改很多数据,造成不必要的操作,添加事务之后就可以重复对一条数据进行操作,并且在返回结果后进行回滚. 2.解决: 原先继承的是 AbstractJUnit ...
- Redis学习笔记~Redis事务机制与Lind.DDD.Repositories.Redis事务机制的实现
回到目录 Redis本身支持事务,这就是SQL数据库有Transaction一样,而Redis的驱动也支持事务,这在ServiceStack.Redis就有所体现,它也是目前最受业界认可的Redis ...
- REDIS 事务机制
基本事务操作: 任何数据库都必须要保证一种原子执行操作:最基本的原子执行操作肯定是需要提供: 举一个例子来说明: 当对某个Key 做一个统计: 可能不同的Client做它那部分的统计,一段时间后,服务 ...
- WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程
今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制. ...
- 一文说清 InnoDB 的事务机制
我们从一个转账的故事开始. 隔壁小王从美团上找到了一家水饺店,准备中午吃水饺.下单成功,支付20元. 商家这里响了一下:叮叮,您有美团外卖新订单啦,请及时处理.水饺一份,好嘞,下锅. 很快小王吃到外卖 ...
- 分享我们项目中基于EF事务机制的架构
写在前面: 1. 本文中单元测试用到的数据库,在执行测试之前,会被清空,即使用空数据库. 2. 本文中的单元测试都是正确通过的. 要理解EF的事务机制,首先要理解这2个类:TransactionSco ...
- springmvc 用注解方式添加事务不生效解决方法
springmvc 事务注册有很多种方法,在此我只mark 用注解方式添加transaction不生效的解决办法. springmvc 注解方法添加事务步骤: 1.在 spring的 root-con ...
- NoSQL生态系统——事务机制,行锁,LSM,缓存多次写操作,RWN
13.2.4 事务机制 NoSQL系统通常注重性能和扩展性,而非事务机制. 传统的SQL数据库的事务通常都是支持ACID的强事务机制.要保证数据的一致性,通常多个事务是不可能交叉执行的,这样就导致了可 ...
随机推荐
- Volley源码学习笔记
标签(空格分隔): Volley 创建RequestQueue 使用Volley的时候,我们首先需要创建一个RequestQueue对象,用于添加各种请求,创建的方法是Volley.newReques ...
- Java基础二
1 关键字 定义:被java语言赋予了特殊含义的单词. 特点:关键字中的所有字母都为小写. 用于定义数据类型的关键字 class.interface.byte.short.int.long.float ...
- Mysql 掌握要点
1. 引擎 InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁. 行级锁和表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题. 1.1 I ...
- Android艺术探索第四 view的自定义
一.初见View View的层级关系(Veiw到底分成几层,自定义view是从那一层开始绘制的) R:Veiw树的结构如下 ,自定义View是从DecorView开始的;DecorView是View树 ...
- html+css手记
----------------------html定义和基本结构---------------------- HTML是 HyperText Mark-up Language 的首字母简写,意思是超 ...
- 互联网世界中的C语言——我的golang学习笔记:1(基础语法快速过)
前言 学习任何知识都会有一个学习背景 最近,我们团队乃至我司整个云服务,上go的呼声越来越高!新服务已经开始用go开发,部分现有Java版的服务重构为go也只是时间问题而已,故相关技术积累势在必行!在 ...
- 几个常用EL表达式的用法
转载至 http://yqsshr.blog.51cto.com/469059/131824 1,用来获取表单数据 param 和 paramValues 1.jsp 的有如下表单 <for ...
- RESTful学习记录
1.1 什么是RESTful RESTful架构,就是目前最流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便,所以正得到越来越多网站的采用. RESTful(即Representat ...
- IPsec_VPN实现技术【转载】
GRE Tunnel GRE Tunnel(General Routing Encapsulation 通用路由封装)是一种非常简单的VPN(Virtual Private Network 虚拟专用网 ...
- 第五次作业2、请将该code进行代码重构,使之模块化,并易于阅读和维护;
1.请运行下面code,指出其功能: (需附运行结果截图,并用简短文字描述其功能) 显示了人的姓名.年龄 2.请将该code进行代码重构,使之模块化,并易于阅读和维护: 3.观看视频The Exper ...