做机房收费系统已经接近尾声了,随着系统业务的完好、对各个过程功能要求的提高,对代码的要求就变的愈加苛刻,非常多时候实现一个功能须要对数据库中非常多的表进行操作,而这些操作都是在这个功能实现了的前提之下才应该去运行的,所以,假设我们单纯地实现功能,而不去考虑他们之间的因果关系,就会出如今某一个功能中部分操作完毕了而其它的操作因为因为终端并没有完毕,终于,就会对我们的数据造成破坏,使系统的性能大大减少,严格地说,这种系统是失败的、不合格的。举例来说,假设你在存钱的时候因为供电影响系统终止,而你已经把钱存到了ATM机中,银行系统中却并没有更新你的数据,这种损失是你我都不想看到的。
下面就是自己在做操作两个数据表的时候因为中间出错而导致仅仅运行了第一个操作,效果就是第一个数据表插入了新的数据,而与之相应的第二个数据表中却并没有更新:
”功能都是随着需求而来的“,正是因为有这种情况出现,所以才有了事务的出现,接下来,我将介绍一下事务:
一、应用背景
上边的样例已经非常好地说明了事务应用的背景,在此不再赘述。
二、应用实例
下面是自己针对某一功能加入了事务之后的效果,D层代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;"> ''' <summary> ''' 注冊学生信息(应用事务) ''' </summary> ''' <param name="enUpdateStu"></param> ''' <param name="enUpdateCard"></param> ''' <remarks></remarks> Public Sub Register(ByVal enUpdateStu As Entity.students, ByVal enUpdateCard As Entity.card, ByVal enUpdateChargeRec As Entity.ChargeRecord) Dim strconnection As String = "server=zhanghui-pc;database=charge-SYS;user id=sa;password=*****" Dim conn As SqlConnection = New SqlConnection(strconnection) Dim cmd As New SqlCommand Using (conn) conn.Open() '开启事务 Dim transaction As SqlTransaction transaction = conn.BeginTransaction() cmd.Transaction = transaction cmd.Connection = conn Try '-------更新学生信息(事务一)--------------------------- Dim sqlstr1 As String = "insert into T_students (stuID,stuName,stuSex,stuMajor,stuGrade,stuClass,cardNO," + "explain) values (@stuID,@stuName,@stuSex," + "@stuMajor,@stuGrade,@stuClass,@cardNO,@explain)" Dim commandtype1 As New CommandType Dim parameter1 As SqlParameter() parameter1 = {New SqlParameter("@stuID", enUpdateStu.stuID), New SqlParameter("@stuName", enUpdateStu.stuName), New SqlParameter("@stuSex", enUpdateStu.stuSex), New SqlParameter("@stuMajor", enUpdateStu.stuMajor), New SqlParameter("@stuGrade", enUpdateStu.stuGrade), New SqlParameter("@stuClass", enUpdateStu.stuClass), New SqlParameter("@cardNO", enUpdateStu.cardNO), New SqlParameter("@explain", enUpdateStu.explain) } cmd.Parameters.AddRange(parameter1) cmd.CommandType = commandtype1 cmd.Connection = conn cmd.CommandText = sqlstr1 cmd.ExecuteNonQuery() '--------------更新卡信息(事务二)------------------------------------------------------------ Dim sqlstr2 As String = "insert into T_card (cardNO,stuID,registerDate,registerTime,registerWorker,cash,status) " + "values (@cardNO2,@stuID2,@registerDate,@registerTime,@registerWorker,@cash2,@status2) " Dim commandtype2 As New CommandType Dim parameter2 As SqlParameter() parameter2 = {New SqlParameter("@cardNO2", enUpdateCard.cardNO), New SqlParameter("@stuID2", enUpdateCard.stuID), New SqlParameter("@registerDate", (Format(Now(), "yyyy/MM/dd"))), New SqlParameter("@registerTime", (Format(Now(), "hh:mm:ss"))), New SqlParameter("@registerWorker", enUpdateCard.registerWorker), New SqlParameter("@cash2", enUpdateCard.cash), New SqlParameter("@status2", enUpdateCard.Status) } cmd.Parameters.AddRange(parameter2) cmd.CommandType = commandtype2 cmd.Connection = conn cmd.CommandText = sqlstr2 cmd.ExecuteNonQuery() '------------------------更新充值记录信息(事务三)------------------------------------- Dim sqlstr3 As String = "insert into T_chargeRecord (cardNO,chargeMoney,chargeDate,chargeTime,userID,status)" + "values (@cardNO3,@chargeMoney,@chargeDate,@chargeTime,@userid,@status3)" Dim commandtype3 As New CommandType Dim parameter3 As SqlParameter() parameter3 = {New SqlParameter("@cardNO3", enUpdateChargeRec.cardNO), New SqlParameter("@chargeMoney", enUpdateChargeRec.chargeMoney), New SqlParameter("@chargeDate", enUpdateChargeRec.chargeDate), New SqlParameter("@chargeTime", enUpdateChargeRec.chargeTime), New SqlParameter("@userid", enUpdateChargeRec.userID), New SqlParameter("@status3", enUpdateChargeRec.status) } cmd.Parameters.AddRange(parameter3) cmd.CommandType = commandtype3 cmd.Connection = conn cmd.CommandText = sqlstr2 cmd.ExecuteNonQuery() '提交事务 transaction.Commit() cmd.Parameters.Clear() Catch ex As Exception '事务回滚 transaction.Rollback() End Try End Using End Sub</span>B层代码,去调用D层
<span style="font-family:KaiTi_GB2312;font-size:18px;"> ''' <summary> ''' 学生注冊(事务) ''' </summary> ''' <remarks></remarks> Public Function RegisterB(ByVal enUpdateStu As Entity.students, ByVal enUpdateCard As Entity.card, ByVal enUpdateChargeRec As Entity.ChargeRecord) As Boolean Dim RegisterD As New DAL.RegisterDAL RegisterD.Register(enUpdateStu, enUpdateCard, enUpdateChargeRec) Try Return True Catch ex As Exception MsgBox(ex.Message) Return False End Try End Function</span>U层代码,调用B层
<span style="font-family:KaiTi_GB2312;font-size:18px;"> Dim RegisterB As New BLL.RegisterBLL RegisterB.RegisterB(entityReg, entityRegCard, entityChargeRec) MsgBox("注冊成功!", vbOKOnly, "恭喜") txtChargeValue.Text = txtValue.Text.Trim</span>三、性质(ACID)
1.攻克了一个功能多个操作中不能所有进行的问题,也就是它的的原子性;
2.使数据库中各个表保持一致,也就是它的一致性;
3.多个事务并发运行会时,系统保证与这些事务先后单独运行时的结果一样,达到了隔离性的要求;
4.操作完毕后,它对数据库的全部更新会永久地反映在数据库中,不会丢失,体现了持久性;
四、总结
事务的使用满足了自己系统中的需求,只是以上代码仅仅是自己研究的结果,自己并非非常惬意,还请大家多多指正。当然,之后自己会在此基础之上加上存储过程,以完好自己的系统,敬请期待!