使用PetaPoco结合注入实现业务级事务

 

PetaPoco是一个轻量级ORM,我的MVC项目中使用它结合Repository模式,依靠Unity的生命周期管理对象,保证请求/线程级别的数据上下文单例,并使用锁和计数实现业务级事务。下文代码依个人理解实现,谬误请不吝指正。

例行IUnitOfWork:

  1. public interface IUnitOfWork
  2. {
  3. void Begin();
  4. void Commit();
  5. void Rollback();
  6. }

仓库上下文核心:

  1. 1 public class PetaPocoUnitOfWork : IUnitOfWork
  2. 2 {
  3. 3 private const String _dbName = "Northwind";
  4. 4 private Boolean _requireAbort = false;
  5. 5 private Int32 _transactionDepth = 0;
  6. 6 private Object _transactionLock = new Object();
  7. 7
  8. 8 public Database DBContext { get; protected set; }
  9. 9
  10. 10 public Guid Id { get; private set; }
  11. 11
  12. 12 public PetaPocoUnitOfWork()
  13. 13 {
  14. 14 Id = Guid.NewGuid();
  15. 15 DBContext = new Database(_dbName);
  16. 16 }
  17. 17
  18. 18 public void Begin()
  19. 19 {
  20. 20 lock (_transactionLock)
  21. 21 {
  22. 22 if (_transactionDepth == 0)
  23. 23 {
  24. 24 DBContext.BeginTransaction();
  25. 25 }
  26. 26 _transactionDepth++;
  27. 27 }
  28. 28
  29. 29 }
  30. 30
  31. 31 public void Commit()
  32. 32 {
  33. 33 lock (_transactionLock)
  34. 34 {
  35. 35 _transactionDepth--;
  36. 36 if (_transactionDepth == 0)
  37. 37 {
  38. 38 try
  39. 39 {
  40. 40 DBContext.CompleteTransaction();
  41. 41 }
  42. 42 catch
  43. 43 {
  44. 44 _transactionDepth++;
  45. 45 _requireAbort = true;
  46. 46 throw;
  47. 47 }
  48. 48 }
  49. 49 }
  50. 50 }
  51. 51
  52. 52 public void Rollback()
  53. 53 {
  54. 54 lock (_transactionLock)
  55. 55 {
  56. 56 _transactionDepth--;
  57. 57 if (_transactionDepth == 0)
  58. 58 {
  59. 59 DBContext.AbortTransaction();
  60. 60 _requireAbort = false;
  61. 61 }
  62. 62 }
  63. 63 }
  64. 64
  65. 65 public void Dispose()
  66. 66 {
  67. 67 if (_requireAbort)
  68. 68 {
  69. 69 DBContext.AbortTransaction();
  70. 70 }
  71. 71 DBContext.Dispose();
  72. 72 }
  73. 73 }

在应用层对Unity注入的IUnitOfWork调用Begin()即开启事务,对于嵌套事务变量_transactionDepth++记录事务深度,Commit()与Rollback()时_transactionDepth--,保证业务中事务只开启与提交一次。如有应用层ITradeService及实现:

  1. 1 public abstract class ApplicationService {
  2. 2 public IUnitOfWork Context { get; private set; }
  3. 3
  4. 4 public ApplicationService(IUnitOfWork context) {
  5. 5 Context = context;
  6. 6 }
  7. 7 }
  8. 8
  9. 9 public interface ITradeService {
  10. 10 void SubmitOrder(Order model);
  11. 11 }
  12. 12
  13. 13 public class TradeService : ApplicationService, ITradeService {
  14. 14 private readonly IOrderRepository _orderRepository;
  15. 15 private readonly IOrderDetailRepository _orderDetailRepository;
  16. 16
  17. 17 public TradeService(
  18. 18 IUnitOfWork context,
  19. 19 IOrderRepository orderRepository,
  20. 20 IOrderDetailRepository orderDetailRepository)
  21. 21 : base(context) {
  22. 22 _orderRepository = orderRepository;
  23. 23 _orderDetailRepository = orderDetailRepository;
  24. 24 }
  25. 25
  26. 26 void SubmitOrder(OrderDTO model){
  27. 27 //do something, like null reference check etc..
  28. 28
  29. 29 Order order = //... some logic
  30. 30 OrderDetail orderDetail = //as above
  31. 31
  32. 32 try {
  33. 33 Context.Begin();
  34. 34
  35. 35 _orderRepository.Update(order);
  36. 36 _orderDetailRepository.Update(orderDetail);
  37. 37 //could be more complex
  38. 38
  39. 39 Context.Commit();
  40. 40 }
  41. 41 catch {
  42. 42 Context.Rollback();
  43. 43 throw;
  44. 44 }
  45. 45 }
  46. 46 }

当顾客提交订单时,Context.Begin()开启一个事务锁,由于Unity的生命周期管理,当前线程内的数据上下文实例是同一个对象,故能够保证事务。当事务发生嵌套时,事务深度的解决方法发生作用,比如以可测试性的提高截取部分代码示例:

  1. [TestClass]
  2. public class AccountServiceTest {
  3. [TestMethod]
  4. public void TradeServiceTest_SubmitOrder() {
  5. IUnitOfWork context = ... //some initialize logic
  6. OrderDTO model = ... //as above
  7. TradeService service = //as above
  8.  
  9. context.Begin();
  10. service.SubmitOrder();
  11. context.Rollback();
  12. ///... etc
  13. }
  14. }
 
 
 
标签: .Net

使用PetaPoco结合注入实现业务级事务的更多相关文章

  1. sql服务器第5级事务日志管理的阶梯:完全恢复模式下的日志管理

    sql服务器第5级事务日志管理的阶梯:完全恢复模式下的日志管理 原文链接http://www.sqlservercentral.com/articles/Stairway+Series/73785/ ...

  2. spring注解实现业务层事务管理,当业务层自调用时,事务失效问题解决

    前些日子一朋友在需要在目标对象中进行自我调用,且需要实施相应的事务定义,且网上的一种通过BeanPostProcessor的解决方案是存在问题的.因此专门写此篇帖子分析why. 1.预备知识 aop概 ...

  3. JDBC基础:JDBC快速入门,JDBC工具类,SQL注入攻击,JDBC管理事务

    JDBC基础 重难点梳理 一.JDBC快速入门 1.jdbc的概念 JDBC(Java DataBase Connectivity:java数据库连接)是一种用于执行SQL语句的Java API,可以 ...

  4. spring项目中service方法开启线程处理业务的事务问题

    1.前段时间在维护项目的时候碰到一个问题,具体业务就是更新已有角色的资源,数据库已更新,但是权限控制不起效果,还是保留原来的权限. 2.排查发现原有的代码在一个service方法里有进行资源权限表的更 ...

  5. servlet注入service业务bean

    项目中用到spring容器来管理业务bean,在servlet中就收到前台传递来的请求参数后,调用业务bean,老是出错 部门代码如下 <span style="font-size:1 ...

  6. c# 业务层事务

    步骤: 1.先添加System.Transactions.dll的引用 2.使用System.Transactions命名空间下的类 实例: using (TransactionScope scope ...

  7. Java之事务的基本应用

    基本介绍 事务是数据一致性最基本的保证,也就是说一个事务中的操作要么都成功,要么都失败,不允许部分成功.我们常说的事务就是jdbc事务,当然Java中还有其他事务,并且在使用jdbc事务有很多注意点, ...

  8. 如何优化MySQL千万级大表

    很好的一篇博客,转载 如何优化MySQL千万级大表 原文链接::https://blog.csdn.net/yangjianrong1985/article/details/102675334 千万级 ...

  9. Web基础之Spring AOP与事务

    Spring之AOP AOP 全程Aspect Oriented Programming,直译就是面向切面编程.和POP.OOP相似,它也是一种编程思想.OOP强调的是封装.继承.多态,也就是功能的模 ...

随机推荐

  1. TLD跟踪算法优化(一)并行化

    才学疏浅,仅仅言片语,仅仅求志同道的朋友一起交流研究. 并行化不算是算法的改进,仅仅是追求执行的实时性. 简要列举一个样例: TLD算法的C++版本号源代码里: LKTracker::trackf2f ...

  2. C# .NET ASP.NET 其中关系你了解多少

    有些人一直在做这方面..但突然有人来问你这些问题..估计有很多答不上来. 1..NET是一个平台,一个抽象的平台的概念. .NET平台其本身实现的方式其实还是库,抽象层面上来看是一个平台. 个人理解. ...

  3. 在windows下用C语言写socket通讯实例

    原文:在windows下用C语言写socket通讯实例 From:Microsoft Dev Center #undef UNICODE #define WIN32_LEAN_AND_MEAN #in ...

  4. JavaScript插件化开发

    大熊君JavaScript插件化开发 一,开篇分析 Hi,大家好!大熊君又和大家见面了,还记得昨天的那篇文章吗------这个系列的开篇(第一季).主要讲述了以“jQuery的方式如何开发插件”, 那 ...

  5. Java获取.properties配置文件某一项value根据key值

    public static String getProperty(String key){ InputStream in = PropertiesUtils.class.getResourceAsSt ...

  6. jQuery选取和操纵元素的特点

    jQuery选取和操纵元素的特点 JavaScript选取元素 先来看看不用jQuery的时候我们是怎么处理元素选取的. JavaScript选取元素的时候,可以根据id获取元素,当id不存在的时候, ...

  7. sbt公布assembly解决jar包冲突 deduplicate: different file contents found in the following

    一个.问题定义 近期使用sbt战斗assembly发生故障时,包,在package什么时候,发生jar包冲突/文件冲突,两个相同class来自不同jar包classpath内心冲突. 有关详细信息:我 ...

  8. Centos中如何配置Texlive2013中文字体的问题

    Centos中如何配置Texlive2013中文字体的问题: 第一步是下载你需要的字体,我从windows/fonts中拷贝的比较多,你只要复制你需要的字体即可. 注意只要文件扩展名为ttf的文件,t ...

  9. 对TextView设置drawable,用setCompoundDrawables方法实现

    在上一项目上需要对TextView在xml文件中设置的drawableLeft的图片进行更改,查询了资料好久也没有找到解决办法,如下代码所示: commentTV.setCompoundDrawabl ...

  10. 代码阅读软件kscope源码安装指导

    安装 kscope-1.6.2 1. ./configure --without-arts --prefix=/soft/kscope-1.6.2  (I customize the installi ...