前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-UDA中处理事务

一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-UDA中处理事务

作者头像
魏琼东
发布2018-01-12 11:08:48
7200
发布2018-01-12 11:08:48
举报
文章被收录于专栏:魏琼东魏琼东
前文回顾

        在之前的文章一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-使用UDA操纵SQL语句和一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-UDA中的委托与应用两篇文章中详细的介绍了如何使用UDA进行常规的业务进行操作,以及AgileEAS.NET平台中UDA的两种数据处理模式对比,以及基于懒惰模式的代理查询。

事务处理

       我们知道在应用开发中,使用单SQL语句进行业务处理永远无法满足复杂的应用,一个业务可以需要2-N条SQL语句的配合才能完成,并且要求处理的数据保持一致性,也就是要求2-N语言要么全部执行成功,要么全部失败,不能产品执行一部分另一部分因为某些原因无法执行,造成数据的不一致。

       .NET的Ado.NET为我们提供了事务处理机制,AgileEAS.ENT平台的统一数据访问(UDA)支持基于ADO.NET的事务处理机制,并对其进行了封装。

处理流程

       标准的事务处理流程是在UDA的数据操作流程的基础上增加事务的打开、提交与回滚三个操作,流程如下:

image
image

       AgileEAS.NET平台的UDA也为事务提供了一种懒得的处理模式,即事务托管执行,应用开发人员在这种模式中不用考虑连接的打和关闭,也不用考虑事务的开始、提交与回滚,而只需要关注应用业务就行。

事务处理的例子

       假定我们需要处理一个商品的入库业务,涉及三个数据表,从商品字典有查出商品字典数据,向商品入库记录表和商品库存表同步写入数据,我们假定实现以单位为采购100单位的商品编码为“1AZ0002094” ,名称为“95%医用酒精”的业务,交易价格为12.5元,处理代码如下: 

 1  /// <summary>
 2  /// 标准流程的事务处理。
 3  /// </summary>
 4  public void DemoTransaction()
 5     {
 6         IDataAccessor accessor = UdaContext.DataAccessor;
 7         accessor.DataConnection.Open();
 8 
 9  try
10         {
11  try
12             {
13                 (accessor.DataConnection as IConnection).BeginTransaction();
14 
15                 ParameterCollection pc = new ParameterCollection();
16                 pc.Add("CODE", "1AZ0002094");
17 
18                 IDictionary<string, object> dc = accessor.QueryDictionary("SELECT * FROM dbo.PRODUCT where CODE= ?", pc);
19  string billCode = DateTime.Now.ToString("yyyyMMddHHmmss");
20 
21                 pc = new ParameterCollection();
22                 pc.Add("BILLCODE", billCode);
23                 pc.Add("CODE", dc["CODE"]);
24                 pc.Add("NAME", dc["NAME"]);
25                 pc.Add("SPEC", dc["SPEC"]);
26                 pc.Add("UNIT", dc["UNIT"]);
27                 pc.Add("PRICE", 12.5M);
28                 pc.Add("NUMBER", 100);
29                 pc.Add("OPERATOR", "james");
30                 pc.Add("INTIME", DateTime.Now);
31 
32  //入库记录
33                 accessor.Execute("INSERT dbo.PIN(IDN,BILLCODE,CODE,NAME,SPEC,UNIT,PRICE,NUMBER,OPERATOR,INTIME) select isnull(max(idn),0)+1,?,?,?,?,?,?,?,?,? from dbo.PIN", pc);
34 
35  //库存
36                 pc = new ParameterCollection();
37                 pc.Add("CODE", dc["CODE"]);
38                 pc.Add("PRICE", 12.5M);
39 
40  int storeRecords = (int)accessor.QueryScalar("SELECT count(*) FROM dbo.PSTORE where CODE= ? and PRICE = ?", pc);
41  if (storeRecords > 0)
42                 {
43                     accessor.QueryScalar("UPDATE dbo.PSTORE Set NUMBER=NUMBER +" + 100 + " where CODE= ? and PRICE = ?", pc);
44                 }
45  else
46                 {
47                     pc = new ParameterCollection();
48                     pc.Add("CODE", dc["CODE"]);
49                     pc.Add("NAME", dc["NAME"]);
50                     pc.Add("SPEC", dc["SPEC"]);
51                     pc.Add("UNIT", dc["UNIT"]);
52                     pc.Add("PRICE", 12.5M);
53                     pc.Add("NUMBER", 100);
54 
55                     accessor.Execute("INSERT dbo.PSTORE(IDN,CODE,NAME,SPEC,UNIT,PRICE,NUMBER) select isnull(max(idn),0)+1,?,?,?,?,?,? from dbo.PSTORE", pc);
56                 }
57 
58                 (accessor.DataConnection as IConnection).CommitTransaction();
59                 System.Console.WriteLine("事务已成功提交。");
60             }
61  catch
62             {
63                 (accessor.DataConnection as IConnection).RollbackTransaction();
64                 System.Console.WriteLine("事务已回滚。");
65  throw;
66             }
67         }
68  finally
69         {
70             accessor.DataConnection.Close();
71         }
72     }

使用事务委托

       上面的单码需要应用开发人管理数据库的打开、关闭,还得处理事务的开始、提交与回滚业务,每个都如些进行处理,容易出错,程序也不是很简洁,在AgileEAS.NET平台的统一数据访问(UDA)中提供了一种更为简洁的事务处理处理方式事务委托,我们定义了TransactionHandler及TransactionHandler2两个事务委托:

    /// <summary>
    /// 定义数据库操作的事务处理委托。该委托将代表客户执行数据库事务,这样使用者不需要考虑事务的开始和结束。
    /// </summary>
    /// <param name="Accessor">数据访问器对象。</param>
    public delegate void TransactionHandler(IDataAccessor Accessor);

    /// <summary>
    /// 定义数据库操作的事务处理委托。该委托将代表客户执行数据库事务,这样使用者不需要考虑事务的开始和结束。
    /// </summary>
    /// <param name="Accessor">数据访问器对象。</param>
    /// <param name="parameters">委托参数。</param>
    public delegate void TransactionHandler2(IDataAccessor Accessor, params object[] parameters);

       在IDataAccessor接口中定义了使用这两个委托的事务委托方法TransactionExecute(托管执行),闲话不说了,我们来使用TransactionExecute改造以上代码:

 1  /// <summary>
 2  /// 委托方式的事务。
 3  /// </summary>
 4  public void DemoTransaction()
 5     {
 6         IDataAccessor accessor = UdaContext.DataAccessor;
 7  try
 8         {
 9             accessor.TransactionExecute(new TransactionHandler(this.InternalSaveData));
10             System.Console.WriteLine("事务已成功提交。");
11         }
12  catch
13         {
14             System.Console.WriteLine("事务已回滚。");
15         }
16     }
17 
18  /// <summary>
19  /// 事务代理方法。
20  /// </summary>
21  /// <param name="accessor"></param>
22  void InternalSaveData(IDataAccessor accessor)
23     {
24         ParameterCollection pc = new ParameterCollection();
25         pc.Add("CODE", "1AZ0002094");
26 
27         IDictionary<string, object> dc = accessor.QueryDictionary("SELECT * FROM dbo.PRODUCT where CODE= ?", pc);
28  string billCode = DateTime.Now.ToString("yyyyMMddHHmmss" +"_1");
29 
30         pc = new ParameterCollection();
31         pc.Add("BILLCODE", billCode);
32         pc.Add("CODE", dc["CODE"]);
33         pc.Add("NAME", dc["NAME"]);
34         pc.Add("SPEC", dc["SPEC"]);
35         pc.Add("UNIT", dc["UNIT"]);
36         pc.Add("PRICE", 12.5M);
37         pc.Add("NUMBER", 100);
38         pc.Add("OPERATOR", "james");
39         pc.Add("INTIME", DateTime.Now);
40 
41  //入库记录
42         accessor.Execute("INSERT dbo.PIN(IDN,BILLCODE,CODE,NAME,SPEC,UNIT,PRICE,NUMBER,OPERATOR,INTIME) select isnull(max(idn),0)+1,?,?,?,?,?,?,?,?,? from dbo.PIN", pc);
43 
44  //库存
45         pc = new ParameterCollection();
46         pc.Add("CODE", dc["CODE"]);
47         pc.Add("PRICE", 12.5M);
48 
49  int storeRecords = (int)accessor.QueryScalar("SELECT count(*) FROM dbo.PSTORE where CODE= ? and PRICE = ?", pc);
50  if (storeRecords > 0)
51         {
52             accessor.QueryScalar("UPDATE dbo.PSTORE Set NUMBER=NUMBER +" + 100 + " where CODE= ? and PRICE = ?", pc);
53         }
54  else
55         {
56             pc = new ParameterCollection();
57             pc.Add("CODE", dc["CODE"]);
58             pc.Add("NAME", dc["NAME"]);
59             pc.Add("SPEC", dc["SPEC"]);
60             pc.Add("UNIT", dc["UNIT"]);
61             pc.Add("PRICE", 12.5M);
62             pc.Add("NUMBER", 100);
63 
64             accessor.Execute("INSERT dbo.PSTORE(IDN,CODE,NAME,SPEC,UNIT,PRICE,NUMBER) select isnull(max(idn),0)+1,?,?,?,?,?,? from dbo.PSTORE", pc);
65         }            
66     }

      是不是发现这种处理方式很简洁呢,本文到此为止,下文我将介绍使用IOC解藕数据库连接对象(数据访问提供者)。

          有关本例子所涉及的数据表结构请参考基于AgileEAS.NET平台基础类库进行应用开发-总体说明及数据定义一文,有关数据对象模型定义文件、文档、DDL脚本请下载:http://files.cnblogs.com/eastjade/demo.db.doc.sql.rar,本文代码下载:UDA.Demo3.rar

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2010-09-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前文回顾
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档