事务是一组组合成
逻辑工作单元的操作,虽然系统中可能会出错,但事务将控制和维护事务中每个操作的一致性和完整性。
基本介绍
.NET Framework 开发员指南
事务是一组组合成逻辑工作单元的操作,虽然系统中可能会出错,但事务将控制和维护事务中每个操作的一致性和完整性。
例如,在将资金从一个帐户转移到另一个帐户的
银行应用中,一个帐户将一定的金额贷记到一个数据库表中,同时另一个帐户将相同的金额借记到另一个数据库表中。由于计算机可能会因停电、网络中断等而出现故障,因此有可能更新了一个表中的行,但没有更新另一个表中的行。如果数据库支持事务,则可以将数据库操作组成一个事务,以防止因这些事件而使数据库出现不一致。如果事务中的某个点发生故障,则所有更新都可以回滚到事务开始之前的状态。如果没有发生故障,则通过以完成状态提交事务来完成更新。
在 .net 中,可以使用 Connection 和 Transaction 对象来控制事务。可以使用 Connection.BeginTransaction 启动本地事务。一旦开始一个事务,就可以使用 Command 对象的 Transaction 属性在该事务中登记命令。然后,可以根据事务组件的成功或失败情况,使用 Transaction 对象提交或回滚在数据源中所做的修改。
还可以使用 Connection.EnlistDistributedTransaction 在现有的
分布式事务中登记。在现有的分布式事务中登记可以
确保当提交或回滚整个分布式事务时,也提交或回滚对数据源所作的代码修改。
以下示例创建一个 OleDbConnection 和一个 OleDbTransaction。它还演示了如何使用 BeginTransaction、Commit 和 Rollback 方法。
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 中;使用
.net实现。下面依次作一下介绍:
方法1:直接写入到sql 中
使用 BEGIN TRANS, COMMIT TRANS, ROLLBACK TRANS 实现:
例如
BEGIN TRANS
DECLARE @orderDetailsError int, @productError int
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 :使用
.net 实现,使用这种方式的优点是可以在中间层来管理事务,当然你也可以选择在数据层来实现。
SqlConnection 和OleDbConnection 对象有一个 BeginTransaction 方法,它可以返回 SqlTransaction 或者OleDbTransaction 对象。而且这个对象有 Commit 和 Rollback 方法来管理事务,具体例子如下:
cnNorthwind.Open()
Dim trans As SqlTransaction = cnNorthwind.BeginTransaction()
Dim cmDel As New SqlCommand()
cmDel.Connection = cnNorthwind
cmDel.Transaction = trans
Try
cmDel.CommandText = _
cmDel.ExecuteNonQuery()
cmDel.ExecuteNonQuery()
trans.Commit()
Catch Xcp As Exception
trans.Rollback()
Finally
cnNorthwind.Close()
End Try
Ok,通过上面的例子可以实现与方法1同样的效果。
并发问题:
如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。并发问题包括: 丢失或覆盖更新,未确认的相关性(脏读),不一致的分析(非重复读),幻像读。但是如何来避免数据读取时脏读等问题出现呢?
实例
using(SqlTransaction trans = conn.BeginTransaction())
{
try
{
//循环进行信息的插入
for(int count = 0; count < applyInfo.Length; count ++)
{
//声明参数并赋值
SqlParameter[] parms =
};
//执行新增操作
}
//未出现错误,则提交事务
trans.Commit();
return true;
}
catch(Exception ex)
{
//出错则回滚
trans.Rollback();
throw ex;
}
}
注意事项
事务的定义必须在连接打开后,提交必须在关闭以前
使用事务时必须及时把事务添加到
sqlCommand中去。