机房收费系统完美设计——事务处理VS三层架构
2013-05-16 00:49
435 查看
事务处理之前我的博客中有介绍的:
SqlTransaction对事务的处理
当然这次也还是以介绍本地事务为主。
上面的博客中只是通过简单的例子介绍事务的应用,但是在三层架构中事务应该怎样使用呢,要弄清楚这一点首先是明白事务、连接、command对象之间的关系
connection对象是数据连接,他决定你链接什么数据库,数据库在哪里
command 对象是查询执行,由他来完成查询语句或执行语句
事务呢,一个连接可以有多个事务。但一个事务只属于一个连接。连接就好像北京到上海的一条铁路,事务就是铁路上的列出,列车可以只有车头,也可以带有好多车厢,火车包括车头都是要到北京的。但是要是要不整列火车到达北京,要不都没有到达。
上面是我对事务的理解。
说说我的三层架构:
我的三层结构中融入了设计模式,其中U层对B层的操作是通过外观模式来操作的。外观模式的作用就是让B层复杂的逻辑统一到一个外观中来。
以注册新卡为例:
注册新卡需要插入学生信息和卡信息。当然是需要放在事务里的。要不都插入成功,要不都不插入。
通过以上我的解说大家应该能想出,事务的开始和结束都要放在外观层的(后面用Fa层代替)但是事务的创建时要在连接的基础上的。也就是Fa层要获得连接。就要在B、D、Factory、IDAL走一遍。然后获得的Transaction,还要以参数的形式传回D层操作。这个过程走下来,我发现自己要改的东西又有很多了。
让我们先看看怎么实现。
这里我找了一部分别人的代码。其中的Sqlhelper写的比较有代表性。给大家分享。当然方法一定不止是有一个的。大家写好的sqlhelper不一定不好。
将事务处理独立出来,该类的功能主要是创建数据库连接,开启事务处理,关闭连接。代码如下:
数据库操作类代码如下:
在DBUtil中,所有具有事务处理的方法都不需要关闭连接,数据库的连接在其开启的地方进行关闭。
在DAL层中,接收来自BLL层的connection,然后调用DBUtil中的方法进行数据的操作。代码如下:
连接的创建,及事务的开启均在BLL层进行,执行完毕后,连接也在该层关闭。代码如下:
说明:
实例代码连接的是MySql数据库
其中他的 DButil 也就是我说的sqlhelper
但是这种方法我也说过需要把Transaction作为参数一层层往下传的。有没有更好的办法呢。一定使用的。方法我们下一篇博客介绍。
SqlTransaction对事务的处理
当然这次也还是以介绍本地事务为主。
上面的博客中只是通过简单的例子介绍事务的应用,但是在三层架构中事务应该怎样使用呢,要弄清楚这一点首先是明白事务、连接、command对象之间的关系
connection对象是数据连接,他决定你链接什么数据库,数据库在哪里
command 对象是查询执行,由他来完成查询语句或执行语句
事务呢,一个连接可以有多个事务。但一个事务只属于一个连接。连接就好像北京到上海的一条铁路,事务就是铁路上的列出,列车可以只有车头,也可以带有好多车厢,火车包括车头都是要到北京的。但是要是要不整列火车到达北京,要不都没有到达。
上面是我对事务的理解。
说说我的三层架构:
我的三层结构中融入了设计模式,其中U层对B层的操作是通过外观模式来操作的。外观模式的作用就是让B层复杂的逻辑统一到一个外观中来。
以注册新卡为例:
注册新卡需要插入学生信息和卡信息。当然是需要放在事务里的。要不都插入成功,要不都不插入。
通过以上我的解说大家应该能想出,事务的开始和结束都要放在外观层的(后面用Fa层代替)但是事务的创建时要在连接的基础上的。也就是Fa层要获得连接。就要在B、D、Factory、IDAL走一遍。然后获得的Transaction,还要以参数的形式传回D层操作。这个过程走下来,我发现自己要改的东西又有很多了。
让我们先看看怎么实现。
这里我找了一部分别人的代码。其中的Sqlhelper写的比较有代表性。给大家分享。当然方法一定不止是有一个的。大家写好的sqlhelper不一定不好。
将事务处理独立出来,该类的功能主要是创建数据库连接,开启事务处理,关闭连接。代码如下:
Imports System.Data.Common Public Class TranUtil Private Sub New() End Sub '开启事务 Public Shared Function BeginTransaction() As IDbTransaction Dim conn As DbConnection = DButil.CreateConnection If conn.State = ConnectionState.Closed Then conn.Open() End If Dim tran As IDbTransaction = conn.BeginTransaction() Return tran End Function '关闭连接 Public Shared Sub Close(ByVal tran As IDbTransaction) If tran IsNot Nothing AndAlso tran.Connection.State = ConnectionState.Open Then tran.Connection.Close() tran = Nothing End If End Sub
数据库操作类代码如下:
Imports System.Data.Common Imports System.Configuration Imports System.Reflection.MethodBase Imports MySql.Data.MySqlClient Imports log4net Public Class DButil Private Shared log As ILog = LogManager.GetLogger(GetCurrentMethod().DeclaringType.ToString) Private Sub New() End Sub ' 创建数据库链接 Public Shared Function CreateConnection() As DbConnection log.Info("创建数据库连接") Try '读取app.config中的连接字符串 Dim sConn As String = ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString '创建数据库连接 Dim dbConn As MySqlConnection = New MySqlConnection(sConn) Return dbConn Catch ex As Exception log.Error(ex) Throw ex End Try End Function '取得DbCommand Public Shared Function GetSqlCommand(ByVal connection As DbConnection, ByVal sqlQuery As String) As DbCommand log.Info("sqlQuery:" & sqlQuery) Try Dim dbCommand As MySqlCommand = connection.CreateCommand dbCommand.CommandText = sqlQuery dbCommand.CommandType = CommandType.Text Return dbCommand Catch ex As Exception log.Error(ex) Throw ex End Try End Function ' 给DbCommand对象的参数赋值 Public Overloads Shared Sub AddParameter(ByVal cmd As DbCommand, ByVal parameterName As String, ByVal value As Object) log.Info("parameterName=" & parameterName & ",value=" & value) Dim dbParameter As DbParameter = cmd.CreateParameter() dbParameter.ParameterName = parameterName dbParameter.Value = value dbParameter.Direction = ParameterDirection.Input cmd.Parameters.Add(dbParameter) End Sub #Region "事务处理" ' 返回单个值,如:单个字段的值或者Count(*)的值,具有事务处理功能 Public Shared Function ExecuteTranScalar(ByVal conn As DbConnection, ByVal cmd As DbCommand) As Object Try If conn.State = ConnectionState.Closed Then conn.Open() End If Dim obj As Object = cmd.ExecuteScalar log.Info("ExecuteScalar Result:" & obj) Return obj Catch ex As Exception log.Error(ex) Throw ex End Try End Function ' 新增,删除,修改,具有事务处理功能 Public Shared Function ExecuteTranNonQuery(ByVal conn As DbConnection, ByVal cmd As DbCommand) As Integer Try If conn.State = ConnectionState.Closed Then conn.Open() End If Dim i As Object = cmd.ExecuteNonQuery log.Info("ExecuteNonQuery Result:" & i) Return i Catch ex As Exception log.Error(ex) Throw ex End Try End Function #End Region End Class
在DBUtil中,所有具有事务处理的方法都不需要关闭连接,数据库的连接在其开启的地方进行关闭。
在DAL层中,接收来自BLL层的connection,然后调用DBUtil中的方法进行数据的操作。代码如下:
主档 Public Function InsertOutStockMain(ByVal tran As IDbTransaction, ByVal arl() As String) As Integer Dim sbSql As New StringBuilder sbSql.Append(" insert into outstockmain(stock_no,stock_date,stock_person,buyer_id)") sbSql.Append(" values(?stock_no,?stock_date,?stock_person,?buyer_id)") Try Dim myCmd As MySqlCommand = DButil.GetSqlCommand(tran.Connection, sbSql.ToString) DButil.AddParameter(myCmd, "?stock_no", arl(0)) DButil.AddParameter(myCmd, "?stock_date", arl(1)) DButil.AddParameter(myCmd, "?stock_person", arl(2)) DButil.AddParameter(myCmd, "?buyer_id", arl(3)) Dim iResult As Integer = DButil.ExecuteTranNonQuery(tran.Connection, myCmd) Return iResult Catch ex As Exception Throw ex End Try End Function '明细档 Private Function InsertOutStockDtl(ByVal tran As IDbTransaction, ByVal dr As DataRow) As Integer Dim sbSql As New StringBuilder sbSql.Append(" insert into outstock(seq_no,stock_no,quatity,in_price,out_price)") sbSql.Append(" values(?seq_no,?stock_no,?quatity,?in_price,?out_price)") Dim iResult As Integer = 0 Try Dim myCmd As MySqlCommand = DButil.GetSqlCommand(tran.Connection, sbSql.ToString) DButil.AddParameter(myCmd, "?seq_no", dr.Item("seq_no")) DButil.AddParameter(myCmd, "?stock_no", dr.Item("stock_no")) DButil.AddParameter(myCmd, "?quatity", dr.Item("quatity")) DButil.AddParameter(myCmd, "?in_price", dr.Item("in_price")) DButil.AddParameter(myCmd, "?out_price", dr.Item("out_price")) iResult = DButil.ExecuteTranNonQuery(tran.Connection, myCmd) Return iResult Catch ex As Exception Throw ex End Try End Function
连接的创建,及事务的开启均在BLL层进行,执行完毕后,连接也在该层关闭。代码如下:
Public Function InsertOut(ByVal arl() As String, ByVal dt As DataTable) As Integer Dim iResult As Integer = 0 Using tran As IDbTransaction = TranUtil.BeginTransaction Try iResult = InsertOutStockMain1(tran, arl) If iResult = 0 Then Throw New BaseException("新增出货主档失败!") End If iResult = 0 For Each dr As DataRow In dt.Rows iResult += InsertOutStockDtl(tran, dr) Next tran.Commit() Return iResult Catch ex As Exception If tran IsNot Nothing Then tran.Rollback() End If Throw ex Finally TranUtil.Close(tran) End Try End Using End Function
说明:
实例代码连接的是MySql数据库
其中他的 DButil 也就是我说的sqlhelper
但是这种方法我也说过需要把Transaction作为参数一层层往下传的。有没有更好的办法呢。一定使用的。方法我们下一篇博客介绍。
相关文章推荐
- 机房收费系统完美设计——事务处理vs三层架构2
- 机房收费系统完美设计——获得系统时间
- 机房收费系统=三层+设计模式
- 组合查询(vb.net+三层架构之机房收费系统)
- 机房收费系统=三层+设计模式
- 机房收费系统完美设计——参数传递+组合查询
- 【VB.NET版机房收费系统】——三层VS七层用户登录
- VB.Net机房收费系统(三层)——用datagirdview 控件显示数据库数据
- 软工文档-机房收费系统:详细设计说明书
- 机房收费系统总结三:代码设计
- 个人重构版机房收费系统事务的使用
- 机房收费系统——三层
- VB.NET版机房收费系统---异常处理
- 机房收费系统合作版——VS2013自带报表
- 机房收费系统--数据库概念结构设计
- 【VB与数据库】机房收费系统设计阶段之上下机
- 【视频】如何设计更加“面向对象”的三层架构系统(2):10分钟搞定Asp.Net和WinForm三层架构系统原型
- 重构机房收费系统—浅谈三层
- 机房收费系统--界面设计,人与软件之间的问题
- (转宝贝记).net 框架设计 签名系统三层架构