`
caobihole
  • 浏览: 961624 次
文章分类
社区版块
存档分类
最新评论

项目总结——再谈事务机制

 
阅读更多

引言:

做机房收费系统时,有研究过在三层架构中添加事务处理的机制。那时候基本是自创的一个方法。因为要访问一个公共的静态变量。当时自然就想到了使用实体类,这样得到公共的Connection以后就可以不用在每个层中传了。同样这次的系统中也用到了事务机制的处理。发现了另一种使用事务机制的好的方法,当然也要拿出来给大家分享下了。

基本思路:

看代码之前,大概说一下这次系统中使用是如何使用事务机制了。事务无非就是同时执行多条sql语句,要保证事务的实现无非就是让执行这几条sql语句在同一个Connection链接下操作。其实事务很简单,不过是和三层混在了一起所以让人无从下手罢了,这次的系统中实现事务机制的方法是把要同时执行的多条sql语句放在D层的一个方法里。如果多条sql语句都没有参数,那么就只需要把这多条的sql语句保存起来然后再传给sqlhelper逐条的执行,如果多条的sql语句都带有参数,那么需要保存的就不止有sql语句还用其对应的参数了。

技术难点:

看到这里大家发现其实主要的技术难点只剩下两个,

1.保存这些sql语句,以及他们可能有的参数,然后对应的取出来。

2.就是把对应的把sql语句自己的参数附加上去。

代码以及说明:

说到现在我想应该让大家看看代码了:(这里的例子是带有参数的sql语句,这个掌握了,不带参数的自然也就掌握了。)

首先是D层确定需要放在同一个事务中处理的sql语句,并保存起来用于送给sqlhelper处理。

 ''' <summary>
    ''' 注册卡号时的事务,需要向学生表,卡表,充值记录中添加信息--韩义
    ''' </summary>
    ''' <param name="enStuCard">附有所有信息的学生卡实体</param>
    ''' <param name="enRecharge">附有所有信息的充值实体</param>
    ''' <returns>bool,true则表示成功,false则表示失败</returns>
    ''' <remarks></remarks>
    Public Function Register(ByVal enStuCard As Entity.StuCardEntity, ByVal enRecharge As Entity.ChargeEntity) As Boolean Implements IDAL.IAffairsDAL.Register
        Dim HashList As New Hashtable '定义hashtable。
        '第一条需要执行的sql语句,以及他的参数。
        Dim sql1 As String = "insert into T_Card(CardNo,StudentNo,Cash,CardType,Creater,Status,IsCheck,Date,Time) values(@CardNo,@StudentNo,@Cash,@CardType,@Creater,@Status,@IsCheck,@Date,@Time)"
        Dim sqlParam1(8) As SqlParameter
        sqlParam1(0) = SqlHelperDAL.AddSqlParameter("@CardNo", SqlDbType.Char, enStuCard.CardNO)
        sqlParam1(1) = SqlHelperDAL.AddSqlParameter("@StudentNo", SqlDbType.Char, enStuCard.StudentNO)
        sqlParam1(2) = SqlHelperDAL.AddSqlParameter("@Cash", SqlDbType.Decimal, CDec(enStuCard.Cash))
        sqlParam1(3) = SqlHelperDAL.AddSqlParameter("@CardType", SqlDbType.VarChar, enStuCard.CardType)
        sqlParam1(4) = SqlHelperDAL.AddSqlParameter("@Creater", SqlDbType.Char, enStuCard.Creater)
        sqlParam1(5) = SqlHelperDAL.AddSqlParameter("@Status", SqlDbType.Char, enStuCard.Status)
        sqlParam1(6) = SqlHelperDAL.AddSqlParameter("@IsCheck", SqlDbType.Char, enStuCard.IsCheck)
        sqlParam1(7) = SqlHelperDAL.AddSqlParameter("@Date", SqlDbType.Char, enStuCard.RegisterDate)
        sqlParam1(8) = SqlHelperDAL.AddSqlParameter("@Time", SqlDbType.Char, enStuCard.RegisterTime)
        '第二条需要执行的语句,以及他的参数
        Dim sql2 As String = "insert into T_Student(StudentNo,StudentName,Sex,Department,Grade,Class) values(@StudentNo,@StudentName,@Sex,@Department,@Grade,@Class)"
        Dim sqlParam2(5) As SqlParameter
        sqlParam2(0) = SqlHelperDAL.AddSqlParameter("@StudentNo", SqlDbType.Char, enStuCard.StudentNO)
        sqlParam2(1) = SqlHelperDAL.AddSqlParameter("@StudentName", SqlDbType.Char, enStuCard.StudentName)
        sqlParam2(2) = SqlHelperDAL.AddSqlParameter("@Sex", SqlDbType.Char, enStuCard.Sex)
        sqlParam2(3) = SqlHelperDAL.AddSqlParameter("@Department", SqlDbType.VarChar, enStuCard.Department)
        sqlParam2(4) = SqlHelperDAL.AddSqlParameter("@Grade", SqlDbType.Char, enStuCard.Grade)
        sqlParam2(5) = SqlHelperDAL.AddSqlParameter("@Class", SqlDbType.Char, enStuCard.ClassName)

        '第三条需要执行的语句以及他的参数
        Dim sql3 As String = "insert into T_Recharge(CardNo,AddMoney,UserID,IsCheck,Date,Time) values(@CardNo,@AddMoney,@UserID,@IsCheck,@Date,@Time)"
        Dim sqlParam3(5) As SqlParameter
        sqlParam3(0) = SqlHelperDAL.AddSqlParameter("@CardNo", SqlDbType.Char, enRecharge.CardNO)
        sqlParam3(1) = SqlHelperDAL.AddSqlParameter("@AddMoney", SqlDbType.Decimal, CDec(enRecharge.AddMoney))
        sqlParam3(2) = SqlHelperDAL.AddSqlParameter("@UserID", SqlDbType.Char, enRecharge.UserID)
        sqlParam3(3) = SqlHelperDAL.AddSqlParameter("@IsCheck", SqlDbType.Char, enRecharge.IsCheck)
        sqlParam3(4) = SqlHelperDAL.AddSqlParameter("@Date", SqlDbType.Char, enRecharge.ChargeDate)
        sqlParam3(5) = SqlHelperDAL.AddSqlParameter("@Time", SqlDbType.Char, enRecharge.Time)
        '把三条sql语句和对应的参数保存到hashtable中
        HashList.Add(sql1, sqlParam1)
        HashList.Add(sql2, sqlParam2)
        HashList.Add(sql3, sqlParam3)
        Try
            '传递个sqlhelper执行
            SqlHelperDAL.ExecuteSqlTran(HashList)
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

这里我们完成注册卡需要同时完成三件事1.注册卡信息。2.注册学生信息。3添加充值记录。
大家通过代码也可以看得出来。代码中我们使用了哈希表保存sql语句以及他们对应的参数,哈希表主要有点是他的存取是键值对型的。想到这个其实我们就解决了问题1.我们现在就可以对应的保存与提取了。
然后我们一起来看sqlheper的代码:

        ''' <summary>
        ''' 执行多条sql语句,实现数据库事务--韩义
        ''' </summary>
        ''' <param name="SQLStringList">sql语句的哈希表</param>
        ''' <remarks></remarks>
        Public Sub ExecuteSqlTran(ByVal SQLStringList As Hashtable)
            Using (conn) '打开数据库连接
                '打开数据库连接  
                conn.Open() '打开数据连接
                Dim trans As SqlTransaction = conn.BeginTransaction() '开始数据库事务
                Using (trans)
                    Try
                        '循环
                        For Each myDE As DictionaryEntry In SQLStringList
                            Dim cmdText As String = myDE.Key.ToString()
                            Dim cmdParms() As SqlParameter = CType((myDE.Value), SqlParameter())
                            PrepareCommand(cmd, conn, trans, cmdText, cmdParms)
                            Dim val As Integer = cmd.ExecuteNonQuery() '调用ExecuteNonQuery函数,返回受影响的行数
                            cmd.Parameters.Clear() '清空参数对象
                        Next
                        trans.Commit() '提交事务
                    Catch ex As Exception
                        trans.Rollback() '事务回滚
                        Throw
                    End Try

                End Using
            End Using
        End Sub


上面的这段代码中包括一个循环,这个循环的主要作用就是取出保存在hashtable中的sql语句以及参数,而且保证不会“乱”。当然这其中还有一个很重要的函数
PrepareCommand这个函数的作用就是把取出来的sql语句和参数,组合在一起。
''' <summary>
        ''' 写入参数--韩义
        ''' </summary>
        ''' <param name="cmd">sqlCommand命令</param>
        ''' <param name="conn">sqlconnection命令</param>
        ''' <param name="trans">事务</param>
        ''' <param name="cmdText">sql语句</param>
        ''' <param name="cmdParms">参数</param>
        ''' <remarks></remarks>
        Public Sub PrepareCommand(ByVal cmd As SqlCommand, ByVal conn As SqlConnection, ByVal trans As SqlTransaction, ByVal cmdText As String, ByVal cmdParms() As SqlParameter)
            If conn.State <> ConnectionState.Open Then
                conn.Open()
            End If
            cmd.Connection = conn '设置连接
            cmd.CommandText = cmdText '设置对数源执行的sql语句
            If Not IsNothing(trans) Then
                cmd.Transaction = trans '设置执行事务
                cmd.CommandType = CommandType.Text
            End If
            If Not IsNothing(cmdParms) Then '如果存在参数
                '遍历每个参数
                For Each parameter As SqlParameter In cmdParms
                    If (parameter.Direction = ParameterDirection.InputOutput Or parameter.Direction = ParameterDirection.Input) And (IsDBNull(parameter.Value)) Then
                        parameter.Value = DBNull.Value '附空值
                    End If
                    cmd.Parameters.Add(parameter) '加入参数
                Next
            End If
        End Sub

这样我们也就解决了第二个问题--就是把对应的把sql语句自己的参数附加上去。

看到这里,事务处理基本已经完成了。对于没有参数的多条sql语句,当然泛型是很好的选择。把多条sql语句保存在一个字符串类型的泛型中,然后向下传递。

总结:

两种在三层中添加事务的处理方式都已经在我的博客中有介绍了。那么让我们来总结,比较一下这两种方法的区别把(另一篇博客地址:http://blog.csdn.net/hy6688_/article/details/8933097)我总结的区别有一下几点:(为了方便说明原来的那篇称第一篇,现在的这篇称第二篇)。
1.第一篇中的方法,没有第二篇的简单、直接。
2.第一篇中的方法可以实现这样的操作:第二条sql语句的执行要依赖与第一条sql语句执行的返回结果。
3.第一篇中的方法把每一个sql语句单独的作为一个方法,这样可以实现简单的复用,如果另一个事务机制的处理需要使用这个方法直接拿来用就可以了。
4.第二篇中的方法,用到的hashtable,方法很巧妙值得学习研究。




分享到:
评论

相关推荐

    Spring Data JPA系列4——Spring声明式事务处理与多数据源支持.doc

    在大部分涉及到数据库操作的项目里面,事务控制、事务处理都是一个无法回避的问题。Spring 框架提供了声明式事务处理机制,使得业务代码中进行事务控制操作起来非常简单。只需加个@Transactional 注解即可,大大简化...

    云应用开发 ——Google App Engine & Google Web Toolkit入门指南

    7.5 事务 7.6 关系 7.7 实例——员工管理系统 第8章 国际化 8.1 普通文本国际化 8.2 参数文本国际化 8.3 实例 第9章 应用托管 9.1 申请Google App Engine账号 9.2 上传应用 9.3 应用维护指南 第10章 实战 10.1 ...

    python通过Canal进行数据监控后的数据缓存设计(csdn)————程序.pdf

    在这个特定的人脸识别项目中,编码阶段的人脸特征被存储到 MySQL 数据库中,而检测阶段则需要快速访问这些数据进行比对。为了优化性能并减少对数据库的频繁查询,引入了数据缓存机制。 Canal 是一个由阿里巴巴开源...

    Android 性能调优和开源代码知识分享

    * 数据库优化:优化数据库的读写操作,使用事务机制,减少数据库的查询次数。 * Java(Android)代码优化:优化 Java 代码,减少对象的创建和销毁,使用缓存机制,避免过多的计算操作。 * 图片缓存:使用图片缓存机制...

    11 支付订单库存消息Mq交互(分布式事务)1

    本文将探讨一种常见的解决方案——使用消息队列,特别是针对支付订单库存消息交互的分布式事务处理。首先,我们来看一下消息队列在分布式事务中的作用。 分布式事务是指跨越多个独立的数据库或服务的事务操作,其...

    职业律师事务所商业实施计划书.doc

    【标题】和【描述】提及的是一个专业咨询机构——中商产业研究院编写的"职业律师事务所商业实施计划书",其旨在为律师事务所项目提供详细的战略规划和市场分析,以吸引投资并指导项目实施。这份计划书涵盖了从项目...

    Java远程通信技术——Axis实战.doc

    Axis 是 Apache 软件基金会的一个开源项目,主要用于简化基于 SOAP 的 Web 服务的开发。Axis 1.x 版本是基于 JAX-RPC 实现的,而 Axis 2.x 则是基于 JAX-WS 标准构建的,这使得 Axis 2.x 在功能和性能上都有了显著...

    香港某建筑设计事务所公司发展战略.pptx

    【HHY建筑设计事务所公司发展战略】\n\n本报告聚焦于香港某知名建筑设计事务所——HHY公司的战略发展规划,旨在为其在中国市场的成长提供指导。该报告由波士顿咨询集团在2003年编制,深入分析了HHY公司所处的内外部...

    房地产公司质量安全评估管理手册.pdf

    《房地产公司质量安全评估管理手册...总结来说,这份手册是中海地产工程管理公司质量管理与安全控制的纲领性文件,通过系统的评估机制和严格的流程控制,旨在打造高品质的房地产项目,提高客户满意度,并降低工程风险。

    asp.net知识库

    也谈 ASP.NET 1.1 中 QueryString 的安全获取写法 ASP.NET运行模式:PageHandlerFactory 利用搜索引擎引用来高亮页面关键字 网站首页的自动语言切换 应用系统的多语言支持 (一) 应用系统的多语言支持 (二) 自动...

    观辰软件OA启航版 v2.5

    计划、任务、分派、执行、报告、总结、发言/点评(自评分、领导评分、桌面当月每日评分/每事评分曲线图)、分析、统计、全面提高日常运营管理活动中任何涉及时间期限安排的事务(合同条款执行、账单缴费、服务项目...

    浅谈我国医院信息化的现状及发展策略.pptx

    2. 联机事务处理:处理日常的前台事务,确保高效运作。 3. 数据汇总与分析:支持管理层的数据收集、分析和报告。 4. 医疗信息的复杂性和标准化:标准化是解决医疗信息复杂性关键,也是HIS发展的瓶颈。 5. 信息安全与...

    数据库课程学习总结.docx

    此外,事务处理和并发控制是课程的重点,包括事务的ACID属性、封锁和隔离级别,以及恢复机制。最后,我们探讨了函数依赖、Armstrong公理和数据库理论,这些都是理解数据库设计和优化的基础。 通过这门课程,我深刻...

    网站网络招商各个岗位职责.doc

    3. 负责公司网站的优化和推广,熟悉网络推广(论坛发帖、社区、email、QQ聊天等)方式,综合应用各种网络推广方式,持之以恒的实施——评估总结——改进——再实施。 * 重要知识点:网站优化、网络推广、论坛发帖、...

    J2EE企业级项目开发-1期 任务3-3 实训项目单.doc

    在本实训项目“BBS管理系统——实现对文章列表增删改查操作的权限检测”中,学生将深入学习和实践JavaEE企业级开发技术,特别是Spring框架的应用。这个任务是针对软件技术专业的学生,旨在提升他们在真实项目环境下...

    JAVA各种系统框架图简介.doc

    此外,Spring ORM模块与多种ORM框架(如JDO、Hibernate、iBatis SQLMap)集成,提供了统一的事务管理和异常处理机制。 接下来,我们转向iBatis,这是一个专注于数据访问层的轻量级框架。iBatis的优势在于它允许...

    Spring.3.x企业应用开发实战(完整版).part2

    10.3.1 Spring事务传播机制回顾 10.3.2 相互嵌套的服务方法 10.4 多线程的困惑 10.4.1 Spring通过单实例化Bean简化多线程问题 10.4.2 启动独立线程调用事务方法 10.5 联合军种作战的混乱 10.5.1 Spring事务管理器的...

    Spring3.x企业应用开发实战(完整版) part1

    10.3.1 Spring事务传播机制回顾 10.3.2 相互嵌套的服务方法 10.4 多线程的困惑 10.4.1 Spring通过单实例化Bean简化多线程问题 10.4.2 启动独立线程调用事务方法 10.5 联合军种作战的混乱 10.5.1 Spring事务管理器的...

    禅道项目管理软件ZenTaoPMS源码包-PHP

    更新日志:禅道 12.5.3 版本修改记录完成的需求实现年度总结的Bug数据区块实现区块的鼠标hover态年度总结实现按公司、部分、个人的范围统计实现年度总结的用例数据区块实现年度总结的需求数据区块实现年度总结的任务...

    亮剑.NET深入体验与实战精要2

    本书既考虑到实际开发中经常遇到的困惑和难题,也分析了解决问题的思路和方法,更总结出项目开发中不可或缺的技术点及思想。读者可以在欣赏一个个有趣例子的过程中,不知不觉具备开发真正商业项目的能力。 本书集...

Global site tag (gtag.js) - Google Analytics