您的位置:首页 > 运维架构 > 网站架构

机房收费系统完美设计——事务处理vs三层架构2

2013-05-25 21:45 435 查看
上一篇博客中简单介绍了事务处理中各个类从中起到的作用、系统设计中为什么要使用事务的处理,以及最简单的在三层架构中通过传递Transaction作为参数最简单的使用事务。 这一篇博客要介绍最后留下的问题。也就是说能不能有更好的办法,不用每次使用事务处理的时候都要在外观层生产事务,然后再作为参数一层层传到需要使用的D层。 但总觉得这样做实在是太麻烦了。而且编码过程中有的这样的想法。现在实现起来需要改动的东西太多了。整个过程中所使用的类都需要修改。学习大话设计模式让我深刻的理解了一句话“不痴迷,不成功。”有没有简单的办法呢??还是这个问题。给大家留了这么长时间解决了。不知道大家有没有想到办法。今天我给大家分享我的方法。 首先明确一件事。就是事物和数据库连接的关系?上篇博客也有提到。现在我还要提出来,这对我们的设计师非常重要的。上一篇我是这样解释的: 一个连接可以有多个事务。但一个事物只属于一个连接。连接就好像北京到上海的一条铁路,事务就是铁路上的列出,列车可以只有车头,也可以带有好多车厢,火车包括车头都是要到北京的。但是要是要不整列火车到达北京,要不都没有到达。 只了解这些好像是不够的,我们还需要知道,对事物的处理是要通过连接的。事物的开始代码:
Dim tran As SqlTransaction
Tran = Conn.BeginTransaction
2.在事物中对数据库进行操作要取得事物操作数据库所使用的连接:
Dim conn As SqlConnection
Conn=Tran.Connection
最后我们还要知道,事务中的所有的操作都必须保证连接处于打开状态,事务处理完毕关闭连接,也就是说,对于不使用事务的sqlhelper封装的处理可以直接在sqlhelper里关闭连接。但是对于使用事务的处理必须在使用的那一层关闭,并且保证关闭前对数据库的处理全部完成。否则就会出现如下类似的错误。当然说了这么多。最重要的还是如何实现对SqlTransaction的保存,这样就可以那一层用就直接拿了。。 提供一个最简单的思路: 在三层架构中没一层都可以访问的就是实体层。可以在实体层建立实体类,把外观层获得的SqlTransaction对象保存在这个类中。这样SqlTransaction就不用以参数的形式向下传递了。 代码如下:实体层
Imports System.Data.SqlClient
Public Class E_TranConn
    Public Shared _Tran As SqlTransaction
    '获得sqlcommand
    Public Shared Function GetCmd() As SqlCommand
        Return _Tran.Connection.CreateCommand
    End Function
    '获得sqlconnection
    Public Shared Function GetConn() As SqlConnection
        Return _Tran.Connection
    End Function
    Public Shared Property Tran() As SqlTransaction
        Get
            Return _Tran
        End Get
        Set(ByVal Value As SqlTransaction)
            _Tran = Value
        End Set
    End Property
End Class
实体类中的变量方法定义为shared ,其他层需要访问时不必实例化直接访问。 外观层以注销卡为例:
''' <summary>
    ''' 点击注销按钮
    ''' </summary>
    ''' <param name="eCard">eCard实体</param>
    ''' <param name="eAbsentCard">eAbsentCard实体</param>
    ''' <returns>是否注销成功</returns>
    ''' <remarks></remarks>
    Public Function AbsentCard(ByVal eCard As E_Card, ByVal eAbsentCard As E_Absentcard) As ArrayList
        Dim tran As SqlTransaction
        Dim flag As Boolean = False
        Dim Conn As SqlConnection
        Dim list As New ArrayList
        Dim Card As New E_Card
        '判断卡号是否存在
        If bCardOperation.HaveCard(eCard) = False Then
            '卡号不存在处理
            Throw New Exception("卡号不存在请重新输入!!")
        End If
        '判断卡是否正在上机
        If bOnComputer.IsOnComputer(eCard) = True Then
            '如果卡号正在上机
            Throw New Exception("此卡正在上机,无法退卡,请先进行下机操作。")
        End If
        '把原来卡中的余额取出来,保存到退卡记录中的退卡金额
        eAbsentCard.AbsentMoney = bCardOperation.GetCardBalance(eCard).Balance
        '设置卡的状态为未使用
        eCard.CardStatic = "未使用"
        '创建事务的connection链接
        Conn = bGetTranConn.GetTranConn()
        '创建事务
        E_TranConn.Tran = Conn.BeginTransaction
        '保存事物到tran
        tran = E_TranConn.Tran
        Try
            '更新卡中余额
            bCardOperation.UpdateCardBalance(eCard)
            '更新卡的状态
            bCardOperation.UpdateCardStatic(eCard)
            '插入退卡记录
            bAbsentCard.InsertAbsentCard(eAbsentCard)
            '提交事务
            tran.Commit()
            '操作成功返回true
            Card.Balance = eAbsentCard.AbsentMoney
            list.Add(Card)
        Catch ex As Exception
            tran.Rollback()
            Throw ex
        Finally
            '关闭事务的connection连接
            'bGetTranConn.CloseTranConn()
        End Try
        Return list
    End Function
B层代码:
Imports DALFactoryImports System.Data.SqlClientImports IDALPublic Class TranConnBll    Public dalFactory As New DALFactory.DALFactory#Region "取得数据连接"    ''' <summary>    ''' 取得数据连接    ''' </summary>    ''' <returns>connection链接</returns>    ''' <remarks></remarks>    Public Function GetTranConn() As SqlConnection        Dim iTranConn As IDAL.ITranConnDALSql        iTranConn = dalFactory.CreatTranConn        Dim conn As SqlConnection        conn = iTranConn.GetTranConnDALSql()        Return conn    End Function#End Region#Region "关闭链接"    ''' <summary>    ''' 关闭链接    ''' </summary>    ''' <remarks></remarks>    Public Sub CloseTranConn()        Dim iTranConn As IDAL.ITranConnDALSql        iTranConn = dalFactory.CreatTranConn        iTranConn.CloseTranConnDALSql()    End Sub#End Region    End Class
D层代码:
#Region "更新卡内余额"    ''' <summary>    ''' 更新卡内余额    ''' </summary>    ''' <param name="eCard">eCard实体</param>    ''' <returns>是否更新成功</returns>    ''' <remarks></remarks>    Public Function UpdateCardBalance(ByVal eCard As Entity.E_Card) As Boolean Implements IDAL.ICardInfoDALSql.UpdateCardBalance        Dim _strSql As String = "Update T_Card set _Balance=@Balance where _CardNo=@CardNo"        Dim param(1) As SqlParameter        param(0) = New SqlParameter("@Balance", eCard.Balance)        param(1) = New SqlParameter("@CardNo", eCard.CardNo)        Dim blnFlag As Boolean = False        blnFlag = s_sqlhelper.ExecuteTranNonQuery(param, _strSql)        Return blnFlag    End Function#End Region
#Region "更新卡状态"    ''' <summary>    ''' 更新卡状态    ''' </summary>    ''' <param name="eCard">eCard实体</param>    ''' <returns>是否更新成功</returns>    ''' <remarks></remarks>    Public Function UpdateCardStatic(ByVal eCard As Entity.E_Card) As Boolean Implements IDAL.ICardInfoDALSql.UpdateCardStatic        Dim _strSql As String = "Update T_Card set _CardStatic=@CardStatic where _CardNo=@CardNo"        Dim param(1) As SqlParameter        param(0) = New SqlParameter("@CardStatic", eCard.CardStatic)        param(1) = New SqlParameter("@CardNo", eCard.CardNo)        Dim blnFlag As Boolean = False        blnFlag = s_sqlhelper.ExecuteTranNonQuery(param, _strSql)        Return blnFlag    End Function#End Region
#Region "插入退卡信息"    ''' <summary>    ''' 插入退卡信息    ''' </summary>    ''' <param name="eAbsentCard">eAbsentCard实体</param>    ''' <returns>是否插入成功</returns>    ''' <remarks></remarks>    Public Function InsertAbsentCard(ByVal eAbsentCard As E_Absentcard) As Boolean Implements IDAL.IAbsentCardDALSql.InsertAbsentCard        Dim _strSql As String = "insert into T_AbsentCard (_CardNo,_AbsentMoney,_UserNo) values (@CardNo,@AbsentMoney,@UserNo)"        Dim param(2) As SqlParameter        param(0) = New SqlParameter("@CardNo", eAbsentCard.CardNo)        param(1) = New SqlParameter("@AbsentMoney", eAbsentCard.AbsentMoney)        param(2) = New SqlParameter("@UserNo", eAbsentCard.UserNo)        Dim blnFlag As Boolean = False        blnFlag = s_sqlhelper.ExecuteTranNonQuery(param, _strSql)        Return blnFlag    End Function#End Region
sqlhelper代码:
#Region "单例模式生成数据库连接connection"    Public Shared ReadOnly Property Getconn() As SqlConnection        Get            If (IsNothing(conn)) Then                SyncLock syncRoot                    If (IsNothing(conn)) Then                        conn = New SqlConnection(dataBase)                        conn.Open()                    End If                End SyncLock            End If            If (conn.State = ConnectionState.Closed) Then                conn.Open()            End If            If (conn.State = ConnectionState.Broken) Then                conn.Close()                conn.Open()            End If            Return conn        End Get    End Property#End Region
#Region "新增,删除,修改,具有事务处理功能 "    Public Shared Function ExecuteTranNonQuery(ByVal value() As SqlParameter, ByVal strSql As String) As Boolean        Dim cmd As SqlCommand = E_TranConn.GetCmd        cmd.Transaction = E_TranConn.Tran        cmd.CommandText = strSql        cmd.Parameters.AddRange(value)        Try            Dim i As Object = cmd.ExecuteNonQuery            If i > 0 Then                Return True            Else                Return False            End If        Catch ex As Exception            Throw (ex)        End Try    End Function#End Region
当然以上的这些只是考虑的本地事务的情况。分布式事务不在研究之列。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: