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

引言:

做机房收费系统时,有研究过在三层架构中添加事务处理的机制。那时候基本是自创的一个方法。因为要访问一个公共的静态变量。当时自然就想到了使用实体类,这样得到公共的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,方法很巧妙值得学习研究。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自己动手做框架是一种非常有挑战性的任务,尤其是对于 ORM(对象关系映射)、MVC(模型-视图-控制器)和IOC(控制反转)这三个框架而言。以下是对这三个框架的简要介绍,以及它们的实现过程。 首先,ORM(对象关系映射)框架是用于将数据库中的表映射为对象的一种技术。在实现ORM框架时,需要定义对象和表之间的映射关系,并提供相应的API来进行数据库的增删改查操作。还需要处理对象之间的关联关系(如一对一、一对多等),并提供事务管理、缓存等功能。 其次,MVC(模型-视图-控制器)框架是一种用于开发Web应用程序的架构模式,将应用程序分为模型、视图和控制器三层。在实现MVC框架时,需要定义模型、视图和控制器的接口,并提供相应的实现。模型负责处理数据逻辑,视图负责展示用户界面,而控制器则负责接收用户请求并进行处理,最后将结果返回给视图进行展示。 最后,IOC(控制反转)框架是一种通过依赖注入来管理对象之间的依赖关系的技术。在实现IOC框架时,需要定义依赖注入的规则,并提供相应的实现。可以使用反射机制来自动实例化对象,并将依赖的对象注入到目标对象中。还需要提供对象的生命周期管理(如单例模式、原型模式等)和对象的配置方式(如XML配置、注解配置等)。 总结来说,自己动手实现ORM、MVC和IOC框架需要掌握相关的技术和知识,并具备良好的设计和编码能力。除了理论知识外,还需要具备实际项目的经验,以便能够更好地设计和实现这些框架。同时,也需要不断学习和改进,跟上技术的发展潮流,以确保框架的高效和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值