本文英文原版:
http://aspnet.4guysfromrolla.com/articles/072705-1.aspx
利用事务维持数据库的一致性
导言:
虽然数据库可以存储大量的数据供我们查询,但如果这些数据是错误的、无意义的那么这些数据和查询功能都变的毫无意义.不过数据库有很多的技术来确保数据的完整性和一致性:primary key约束和unique约束用于确保实体完整性;foreign key约束确保关系完整性,而事务transactions则确保数据库的数据维持一致性.
虽然INSERT, UPDATE,和DELETE statement是对数据库最常见的操作,但在有些时候我们想将多个INSERT, UPDATE, 和/或DELETE statements当作一个原子操作(atomic operation)来对待.也就是说,在某些情况下,我们不想把每个INSERT, UPDATE,和DELETE statement单独对待,而是将一系列的这些statement作为不可分割的整体的进行处理.当发出这些statement时,我们希望它们要么都执行成功,要么都执行失败——不应该有一些成功一些失败的情况发生.
比较典型的事务案例是将money从一个帐户转到另一个帐户上.银行处理money帐户转移要处理2个步骤;如果我们从经常帐户上转$500到储蓄存款帐户上,我们应处理下面的2个步骤:
.首先,必须从经常帐户上扣除$500;
.然后,将这$500增加到储蓄存款帐户上;
Transaction示例
在考察建立一个事务所必需的.NET代码之前,我们先讨论需要用到事务的比较常见的场合.前面我们提到了使用事务的典型场景——现金转帐.如果你要对一个或多个table执行多个修改命令——INSERT, UPDATE,或DELETE——且这些行为需要作为一个整体作为原子单元的时候,那么你就要使用到事务了.
比较常见的例子是在一个数据库里有2个或更多的有父/子关系的表的情况.当从父表删除一条记录时,你需要删除相关的子记录(或为这些子记录重新分配父关系).因此,当你要删除一个父记录时,你应该包含2个SQL statements,比如:
-- DELETE child records
DELETE FROM ChildTable
WHERE ParentID = IDofParentBeingDeleted
-- DELETE parent record
DELETE FROM ParentTable
WHERE ParentID = IDofParentBeingDeleted
另一个比较常见的例子是,你有2个逻辑相关的表,当添加或更新一个表时,也需要同时添加或更新另一个表.比如,假设有一个在线汽车保险网站,你除了要提交于保险相关的信息——日期、年龄、婚姻关系等之外,你可能还要提供你知晓该网站的途径——广播、电视、朋友等等.当点击提交后,网站会做2个添加记录动作——一个是与保险相关的,另一个是登陆者找到该网站的途径信息.
事务不仅可以保护免受流程步骤中断而带来的意想不到的灾难事故影响,也可以保护免受意想不到的与SQL相关的错误.比如,假想你有5个UPDATE指令,你想把它作为一个逻辑上一组的、单一的原子操作.但是不管是什么原因,第5个UPDATE指令包含了一个非法的值,并导致错误.如果没有事务的话,第5条指令不会更新数据库,但前面4条记录会,这样一来,在逻辑上数据库就陷入一种逻辑不一致的状态.
事务的通常步骤
使用事务时,一般来说你要用到下面的步骤:
1.明确指出你想开启一个事务.所有的指令从此时起在逻辑上都是原子操作的一部分
2.发出指令——那些包含在事务里的INSERT, UPDATE,和DELETEs
3.如果出错,回滚事务.回滚的作用在于前面执行的指令都无效.
4.如果全部正常,则提交事务.通过事务对数据库更新.
因为事务是"原子的",所有如果有任何的突然事故——比如断电、数据库服务器发生碰撞等——事务就会回滚,确保系统的一致性.
当通过.NET来处理事务时,你将开启事务,再通过事务对象来发出一系列的指令.当执行SQL statements出错时用Try ... Catch来捕获异常,此时你可以回滚事务。如果没有出错则提交事务.
用SqlTransaction Class类处理事务
如果你用的是Microsoft SQL Server,那么你就可以使用System.Data.SqlClient.SqlTransaction class类来开启一个事务.首先通过SqlConnection class类来打开一个到数据库的连接,然后调用SqlConnection class类的BeginTransaction()方法来创建一个事务实例,如下:
'Create a connection
Dim myConnection As New SqlConnection(myConnString)
myConnection.Open()
'Start the transaction
Dim myTrans As SqlTransaction = myConnection.BeginTransaction
接下来,你要创建一个用来发出指令的SQL statements的SqlCommand对象.当创建该对象后,你需要指定它使用ID为myTrans的SqlTransaction对象.你可以通过通过构造器来指派,或者通过SqlCommand的Transaction属性来指派.
... Continued from above ...
Try
'Specify the first statement to run...
Dim sql as String = "INSERT INTO ..."
'Create the SqlCommand object, specifying the transaction through
'the constructor (along with the SQL string and SqlConnection)
'Alternatively, could set properties of myCommand
'to specify the Connection, CommandText, and Transaction...
Dim myCommand as New SqlCommand(sql, myConnection, myTrans)
注意,我们已经有了SqlCommand对象,并且在Try ... Catch模块里发出对数据库的指令,此时,你就可以继续发出对数据库的指令了:
... Continued from above ...
myCommand.ExecuteNonQuery()
'Issue another INSERT
myCommand.CommandText = "INSERT INTO ..."
myCommand.ExecuteNonQuery()
... Lather, rinse, repeat as needed! ...
'If we reach here, all command succeeded, so commit the transaction
myTrans.Commit
Catch ex as Exception
'Something went wrong, so rollback the transaction
myTrans.Rollback()
Throw 'Bubble up the exception
Finally
myConnection.Close()'Finally, close the connection
End Try
要做的就这些了!你可以向数据库发出剩下的那些相关的SQL statements.注意,如果发生任何的错误将回滚事务,如果一切无误的话则提交事务.不过管是否引发异常都将执行Finally模块里的代码,关闭数据库连接.
Maintaining Transactions in T-SQL
你也可以直接用T-SQL语法来管理事务.而不用在你的代码里使用SqlTransaction class类,你可以将transaction syntax转移到一个存储过程里(也就是用多个statement来改动数据).具体信息请参考文章《Managing Transactions in SQL Server Stored Procedures》
结语:
在本文我们考察了数据库事务的概念,以及如何在.NET里将SQL statement封装到一个事务里.在创建ASP.NET数据驱动应用程序时维护你的数据的一致性是很重要的.当多个INSERT, UPDATE,或DELETE statements构成一个逻辑上的原子操作时,我们很有必要将这些statement封装到一个事务里.
祝编程快乐!
分享到:
相关推荐
spring事务与数据库操作
数据库事务总结数据库事务总结数据库事务总结数据库事务总结
Oracle SOA 套件和 RAC 数据库事务一致性配置指南
SqlServer实验四:事务与数据库备份.doc SqlServer实验四:事务与数据库备份.doc SqlServer实验四:事务与数据库备份.doc SqlServer实验四:事务与数据库备份.doc SqlServer实验四:事务与数据库备份.doc SqlServer...
Visual C++源代码 112 如何使用事务管理删除数据库记录Visual C++源代码 112 如何使用事务管理删除数据库记录Visual C++源代码 112 如何使用事务管理删除数据库记录Visual C++源代码 112 如何使用事务管理删除数据库...
事务和数据库对象事务和数据库对象
所谓事务是用户定义的一个操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位。
数据库事务管理数据库事务管理
一致性:事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。 隔离性:一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对 其他并发事务是隔离的,并发执行的各个事务之间不...
事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位。SQL Server提供了几种自动的可以通过编程...当用户对数据库并发访问时,为了确保事务完整性和数据库一致性,需要使用锁定
HibernateSHibernateSpring数据库的事务HibernateSpring数据库的事务HibernateSpring数据库的事务pring数据库的事务
思极有容事务型数据库是一款国产自主可控的分布式关系型数据库集群软件,客户端、应用程序使用该数据库集群软件,无需关心真实的数据分布。当数据量、负载增大时,数据库集群可以无限制的动态扩展数据节点,以满足...
近日,腾讯云发布了分布式数据库解决方案(DCDB),其最明显的特性之一就是提供了高于开源分布式事务XA的...虽然分布式数据库能解决性能难题,但事务一致性(Consistency)的问题,却很难在分布式数据库上得到解决。
用生动的PPT动画演示和配套总结性文字,讲述分布式事务数据库的教科书式技术架构、三种主流金融行业技术架构、金标委定义技术架构、行业专业术语,及重点围绕分布式事务数据库的核心技术之分布式事务的原理、功能和...
摘要:先分析了数据库管理系统中的事务处理,接着分析了多层结构及其在...一致,既分别在客户端如何利用显式事务处理、在中间层如何利用隐式事务处理、在远程数据库服 务器层如何利用触发器事务处理来实现数据一致。
整理了一下关于mysql的前因后果,以及如何避免隐式提交
C#数据库事务原理及实践,C#数据库事务原理及实践
数据库安全事务与锁数据库安全事务与锁数据库安全事务与锁
数据库事务:对数据库事务的讲解,事务的概念 理解事务的特性、分类