2010-08-04 80 views
1

我做了一个简单的测试,以了解交易.NET是如何工作的如何.NET的交易上的SQL Server数据库时进行了小分析

上我的交易测试已完成的示例代码是

_sqlHelper = new SqlHelper(true); 
try 
{ 
    _sqlHelper.ExecuteNonQuery(SpName.sp_UpdateRoomStatus.ToString() 
     , Parameters.SqlParam<int?>("DepartmentId", this.DepartmentId, SqlDbType.Int) 
     ); 

    _sqlHelper.ExecuteNonQuery(SpName.sp_UpdateRoomStatus.ToString() 
     , Parameters.SqlParam<int?>("DepartmentId", this.DepartmentId, SqlDbType.Int) 
     ); 

    _sqlHelper.CommitTransaction(); 
} 
catch (SqlHelperException ex) 
{ 
    _sqlHelper.RollBackTransaction(); 
} 

说明关于测试

当我写入新提供SQLHelper(真);一个新的事务在内部开始,连接已经创建并打开到数据库。

_sqlHelper.ExecuteNonQuery(SpName.sp_UpdateRoomStatus.ToString() 
    , Parameters.SqlParam<int?>("DepartmentId", this.DepartmentId, SqlDbType.Int) 
    ); 

上面的函数执行我的过程并在数据库中执行更改。

我写了两次相同的函数调用来执行两次过程。该过程在数据库中进行插入。此过程在3个不同的表中包含3个插入查询。 现在我标记了两个函数调用的断点。

只要第一个断点处于控制状态,我就简单地让它的处理完成,这意味着第一个程序已经完成了插入。

现在我拔掉了我的LAN线,因为DB在远程系统上。这意味着连接丢失。因此事务被回滚。

现在当我在整个过程完成后验证数据库。我发现数据处于一致状态,从而证明交易正在进行。

我很困惑,因为程序成功执行,此时从第一个过程调用发生了实际插入。 sql服务器如何得知通知事务正在进行并且必须进行回滚。

看起来好像连接已建立到数据库通知连接包含事务,并且应该在连接丢失时回滚。

因此也说明所做的更改在数据库而不是.net环境下进行。

回答

1

数据库知道连接和更改应该在事务中 - 实际更改和原始数据存储在数据库事务日志中。当事务未正确提交并且连接丢失时,数据库自动回滚事务。

基本上,在SqlTransactions(不是分布式的)中,.Net没有什么聪明,它都是由数据库处理的。

+0

但是,数据库如何知道更多查询仍在队列中执行。所有查询都是原子的。与数据库的连接是否始终被视为单个事务? – 2010-08-04 10:50:15

+0

它不知道还有更多的东西,它只知道COMMIT命令没有被调用,所以自事务开始以来的任何事情都应该回滚。 – cjk 2010-08-04 10:54:33

+0

但是谁在调用Commit命令。没有人通知数据库,当事务开始时以及它被提交时,除非我们明确指定事务,否则每个查询都被视为单个事务,那么数据库如何才能知道完整批次必须被视为单个事务。因此调用commit – 2010-08-04 11:00:15

相关问题