机房收费系统完美设计——事务处理vs三层架构2
2013-05-25 21:45
435 查看
上一篇博客中简单介绍了事务处理中各个类从中起到的作用、系统设计中为什么要使用事务的处理,以及最简单的在三层架构中通过传递Transaction作为参数最简单的使用事务。 这一篇博客要介绍最后留下的问题。也就是说能不能有更好的办法,不用每次使用事务处理的时候都要在外观层生产事务,然后再作为参数一层层传到需要使用的D层。 但总觉得这样做实在是太麻烦了。而且编码过程中有的这样的想法。现在实现起来需要改动的东西太多了。整个过程中所使用的类都需要修改。学习大话设计模式让我深刻的理解了一句话“不痴迷,不成功。”有没有简单的办法呢??还是这个问题。给大家留了这么长时间解决了。不知道大家有没有想到办法。今天我给大家分享我的方法。 首先明确一件事。就是事物和数据库连接的关系?上篇博客也有提到。现在我还要提出来,这对我们的设计师非常重要的。上一篇我是这样解释的: 一个连接可以有多个事务。但一个事物只属于一个连接。连接就好像北京到上海的一条铁路,事务就是铁路上的列出,列车可以只有车头,也可以带有好多车厢,火车包括车头都是要到北京的。但是要是要不整列火车到达北京,要不都没有到达。 只了解这些好像是不够的,我们还需要知道,对事物的处理是要通过连接的。事物的开始代码:
Dim tran As SqlTransaction Tran = Conn.BeginTransaction2.在事物中对数据库进行操作要取得事物操作数据库所使用的连接:
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 FunctionB层代码:
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 ClassD层代码:
#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 Regionsqlhelper代码:
#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当然以上的这些只是考虑的本地事务的情况。分布式事务不在研究之列。
相关文章推荐
- 机房收费系统完美设计——事务处理VS三层架构
- 机房收费系统=三层+设计模式
- 机房收费系统完美设计——参数传递+组合查询
- 【VB.NET版机房收费系统】——三层VS七层用户登录
- 机房收费系统完美设计——获得系统时间
- 机房收费系统=三层+设计模式
- 组合查询(vb.net+三层架构之机房收费系统)
- 机房收费系统数据库概念结构设计
- (五)机房收费系统详细设计说明书
- 项目手记 (一) 重构机房收费系统--关于架构的第一次认识
- 机房收费系统中的Grid++Report报表设计器的应用
- 设计机房收费管理系统的偏差和认识
- 机房收费系统(二)报表的设计Grid 的使用
- 机房收费系统VB版(三)——窗体设计
- 数据库设计说明书——机房收费系统
- 【机房收费系统个人版】三层登陆
- 设计机房收费管理系统的偏差和认识
- 【个人机房重构】——三层架构,系统登录
- 机房收费系统小结(只用三层做的)
- 机房收费系统--数据库设计小结