c#事务的使用、示例及注意事项 转

摘要:
如果数据库支持事务,则可以将数据库操作组成一个事务,以防止因这些事件而使数据库出现不一致。如果没有发生故障,则通过以完成状态提交事务来完成更新。一旦开始一个事务,就可以使用Command对象的Transaction属性在该事务中登记命令。然后,可以根据事务组件的成功或失败情况,使用Transaction对象提交或回滚在数据源中所做的修改。在执行事务时,.NETFramework数据提供程序使用IsolationLevel值。如果在事务期间更改,服务器的预期行为是,对其余所有语句应用新的锁定级别。
一、事务的介绍

.NET Framework 开发员指南
事务是一组组合成逻辑工作单元的操作,虽然系统中可能会出错,但事务将控制和维护事务中每个操作的一致性和完整性。
例如,在将资金从一个帐户转移到另一个帐户的银行应用中,一个帐户将一定的金额贷记到一个数据库表中,同时另一个帐户将相同的金额借记到另一个数据库表中。由于计算机可能会因停电、网络中断等而出现故障,因此有可能更新了一个表中的行,但没有更新另一个表中的行。如果数据库支持事务,则可以将数据库操作组成一个事务,以防止因这些事件而使数据库出现不一致。如果事务中的某个点发生故障,则所有更新都可以回滚到事务开始之前的状态。如果没有发生故障,则通过以完成状态提交事务来完成更新。
在 ADO.NET 中,可以使用 Connection 和 Transaction 对象来控制事务。可以使用 Connection.BeginTransaction 启动本地事务。一旦开始一个事务,就可以使用 Command 对象的 Transaction 属性在该事务中登记命令。然后,可以根据事务组件的成功或失败情况,使用 Transaction 对象提交或回滚在数据源中所做的修改。
还可以使用 Connection.EnlistDistributedTransaction 在现有的分布式事务中登记。在现有的分布式事务中登记可以确保当提交或回滚整个分布式事务时,也提交或回滚对数据源所作的代码修改。
以下示例创建一个 OleDbConnection 和一个 OleDbTransaction。它还演示了如何使用 BeginTransaction、Commit 和 Rollback 方法。

publicvoidRunOleDbTransaction(stringmyConnString)
{
OleDbConnectionmyConnection
=newOleDbConnection(myConnString);
myConnection.Open();
OleDbCommandmyCommand
=myConnection.CreateCommand();
OleDbTransactionmyTrans;
//StartalocaltransactionmyTrans=myConnection.BeginTransaction(IsolationLevel.ReadCommitted);
//AssigntransactionobjectforapendinglocaltransactionmyCommand.Connection=myConnection;
myCommand.Transaction
=myTrans;
try
{
myCommand.CommandText
=/"InsertintoRegion(RegionID,RegionDescription)VALUES(100,/'Description/')/";
myCommand.ExecuteNonQuery();
myCommand.CommandText
=/"InsertintoRegion(RegionID,RegionDescription)VALUES(101,/'Description/')/";
myCommand.ExecuteNonQuery();
myTrans.Commit();
Console.WriteLine(
/"Bothrecordsarewrittentodatabase./");
}
catch(Exceptione)
{
try
{
myTrans.Rollback();
}
catch(OleDbExceptionex)
{
if(myTrans.Connection!=null)
{
Console.WriteLine(
/"Anexceptionoftype/"+ex.GetType()+/"wasencounteredwhileattemptingtorollbackthetransaction./");
}
}
Console.WriteLine(
/"Anexceptionoftype/"+e.GetType()+/"wasencounteredwhileinsertingthedata./");
Console.WriteLine(
/"Neitherrecordwaswrittentodatabase./");
}
finally
{
myConnection.Close();
}
}

OleDbTransaction.Commit 方法
提交数据库事务。
public virtual void Commit();
OleDbTransaction.Rollback 方法
从挂起状态回滚事务。
public virtual void Rollback();
OleDbConnection.BeginTransaction 方法
开始数据库事务。
public OleDbTransaction BeginTransaction();
以当前的 IsolationLevel 值开始数据库事务。
public OleDbTransaction BeginTransaction(IsolationLevel);
IsolationLevel 枚举?
指定连接的事务锁定行为。 在执行事务时,.NET Framework 数据提供程序使用 IsolationLevel 值。在显式更改之前,IsolationLevel 保持有效,但是可以随时对它进行更改。新值在执行时使用,而不是在分析时使用。如果在事务期间更改,服务器的预期行为是,对其余所有语句应用新的锁定级别。
IsolationLevel成员 ReadCommitted
在正在读取数据时保持共享锁,以避免脏读,但是在事务结束之前可以更改数据,从而导致不可重复的读取或幻像数据。
OleDbConnection.CreateCommand 方法
创建和返回一个与 OleDbConnection 相关联的 OleDbCommand 对象。
public OleDbCommand CreateCommand();
OleDbCommand.Connection 属性
获取或设置 OleDbCommand 的此实例使用的 OleDbConnection。
public OleDbConnection Connection {get; set;}

如何在.NET中实现事务(1)
如何在.NET中实现事务机制呢? 通常可以使用2种方式: 直接写入到sql 中;使用ADO.NET 实现。下面依次作一下介绍:
方法1:直接写入到sql 中
使用 BEGIN TRANS, COMMIT TRANS, ROLLBACK TRANS 实现:
例如
BEGIN TRANS
DECLARE @orderDetailsError int, @productError int
DELETE FROM /"Order Details/" WHERE ProductID=42
SELECT @orderDetailsError = @@ERROR
DELETE FROM Products WHERE ProductID=42
SELECT @productError = @@ERROR
IF @orderDetailsError = 0 AND @productError = 0
COMMIT TRANS
ELSE
ROLLBACK TRANS
这种方法比较简单,具体可以查阅相关sql server 帮助

方法2 :使用ADO.NET 实现,使用这种方式的优点是可以在中间层来管理事务,当然你也可以选择在数据层来实现。
SqlConnection 和OleDbConnection 对象有一个 BeginTransaction 方法,它可以返回 SqlTransaction 或者OleDbTransaction 对象。而且这个对象有 Commit 和 Rollback 方法来管理事务,具体例子如下:

cnNorthwind.Open()
DimtransAsSqlTransaction
=cnNorthwind.BeginTransaction()
DimcmDelAsNewSqlCommand()
cmDel.Connection
=cnNorthwind
cmDel.Transaction
=trans
Try
cmDel.CommandText
=_
/"DELETE[OrderDetails]WHEREProductID=42/"
cmDel.ExecuteNonQuery()
cmDel.CommandText
=/"DELETEProductsWHEREProductID=42/"
cmDel.ExecuteNonQuery()
trans.Commit()
CatchXcpAsException
trans.Rollback()
Finally
cnNorthwind.Close()
EndTry

Ok,通过上面的例子可以实现与方法1同样的效果。

并发问题:

如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。并发问题包括: 丢失或覆盖更新,未确认的相关性(脏读),不一致的分析(非重复读),幻像读。但是如何来避免数据读取时脏读等问题出现呢?
二、事务实例
using(SqlTransaction trans = conn.BeginTransaction())
{
try
{
//循环进行信息的插入
for(int count = 0; count < applyInfo.Length; count ++)
{
//声明参数并赋值
SqlParameter[] parms =
{ Database.MakeInParam (/"@Stu_ID/",System.Data.SqlDbType.VarChar,11,applyInfocount].StuID),
Database.MakeInParam/"@Bank_Name/",System.Data.SqlDbType.VarChar,50,applyInfo[count].BankName), Database.MakeInParam/"@Apply_Loan_Money/",System.Data.SqlDbType.Money,8,applyInfo[count].ApplyLoanMoney), Database.MakeInParam(/"@Apply_Loan_Year/",System.Data.SqlDbType.VarChar,20,applyInfo[count].ApplyLoanYear), Database.MakeInParam/"@Apply_Year/",System.Data.SqlDbType.Char,6,applyInfo[count].ApplyYear), Database.MakeInParam(/"@Apply_Length/",System.Data.SqlDbType.Int,4,applyInfo[count].ApplyLength), Database.MakeInParam(/"@Apply_Pass/",System.Data.SqlDbType.Char,1,applyInfo[count].ApplyPass),
Database.MakeInParam(/"@Apply_Remark/",System.Data.SqlDbType.VarChar,100,applyInfo[count].ApplyRemark)
};
//执行新增操作
SqlHelper.ExecuteNonQuery(trans,CommandType.StoredProcedure, /"ApplyInfo_Create/", parms);
}
//未出现错误,则提交事务
trans.Commit();
return true;
}
catch(Exception ex)
{
//出错则回滚
trans.Rollback();
throw ex;
}
}
四、注意事项
事务的定义必须在连接打开后,提交必须在关闭以前
使用事务时必须即是把事务添加到sqlCommand中去。

免责声明:文章转载自《c#事务的使用、示例及注意事项 转》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Unity3D之Mesh(一)绘制三角形C#打造秒杀腾讯的仿QQ界面,从此独孤求败下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Hibernate 缓存机制

一、why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库。 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。 缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。 二、what(Hibernate缓存原理是怎样的?)Hi...

数据库并发处理

为什么要有锁? 我们都是知道,数据库中锁的设计是解决多用户同时访问共享资源时的并发问题。在访问共享资源时,锁定义了用户访问的规则。根据加锁的范围,MySQL 中的锁可大致分成全局锁,表级锁和行锁三类。在本篇文章中,会依次介绍三种类型的锁。在阅读本篇文章后,应该掌握如下的内容: 为什么要在备份时使用全局锁? 为什么推荐使用 InnoDB 作为引擎进行备份?...

MySql数据库优化、备份和恢复

一、数据库优化 1、为什么要优化 系统的吞吐量瓶颈往往出现在数据库的访问速度上 随着应用程序的运行,数据库的中的数据会越来越多,处理时间会相应变慢 数据是存放在磁盘上的,读写速度无法和内存相比 优化原则:减少系统瓶颈,减少资源占用,增加系统的反应速度。 2、数据库结构优化 需要考虑数据冗余、查询和更新的速度、字段的数据类型是否合理等多方面的内容。 将...

一文带你了解微服务架构和设计(多图)

最近几年微服务很火,大家都在建设微服务,如果不懂点微服务相关的技术,都不好意思跟同行打招呼了,也见过身边很多人在微服务踩过很多坑,我从 16 年开始接触微服务,有多家大型企业的微服务分布式系统的架构经验,所以就打算跟大家做一期关于微服务的分享,不过微服务和涉及的分布式计算非常的复杂,绝非是一篇文章就可以讲清楚的,本文只是从最简单的概念的基本使用带你入门,...

MySQL 数据同步

  在当今互联网行业,大多数人互联网从业者对"单元化"、"异地多活"这些词汇已经耳熟能详。而数据同步是异地多活的基础,所有具备数据存储能力的组件如:数据库、缓存、MQ等,数据都可以进行同步,形成一个庞大而复杂的数据同步拓扑。   本文将先从概念上介绍单元化、异地多活、就近访问等基本概念。之后,将以数据库为例,讲解在数据同步的情况下,如何解决数据回环、数据冲...

ActiveMQ之JMS及保证消息的可靠性&amp;lt;持久化、事务、签收&amp;gt;(三)

1.JAVAEE 是一套使用Java 进行企业级开发的13 个核心规范工业标准 , 包括:  JDBC  数据库连接  JNDI  Java的命名和目录接口  EJB   Enterprise java bean  RMI   远程方法调用    一般使用TCP/IP 协议  Java IDL    接口定义语言  JSP      Servlet   X...