0

我有一个非常重要的问题需要帮助。我将尝试将问题简化为以下示例:

有一个 wcf/web 服务实现(但它可以是任何其他模块),如下所示:

public class Svc: ISvc
{
   public void PerformSimpleOperations()
   {
      try
      {
          // insert in other tables here (calling stored procs)

          /* important line here */
          dbHandler.InsertRecordInSpecificTable(recordType1);

          // commit transaction (default isolation level)
          dbHandler.CommitTransactDB();
      }
      catch
      {
          dbHandler.RollbackTransactDB();
      }
   }
   public void PerformComplexOperations()
   {
      try
      {
          // some complex operations here involving db (calling stored procs)

          /* important lines here */
          dbHandler.InsertRecordInSpecificTable(recordBEGIN);    
          foreach (var recordType2 in arrayOfRecordsType2)
              dbHandler.InsertRecordInSpecificTable(recordType2);    
          dbHandler.InsertRecordInSpecificTable(recordEND);    

          // commit transaction (default isolation level)
          dbHandler.CommitTransactDB();
      }
      catch
      {
          dbHandler.RollbackTransactDB();
      }
   }
}

有 2 种不同的方法可以将基于事务的记录(具有默认隔离级别的ADO.NET SQLTransaction )插入数据库中的一个“特定表”(当然,不同线程随时调用)。

从示例中可以看出,第一种方法只插入简单的'type1'记录,但第二种方法插入大量的'type2'记录,以一些'BEGIN''END'标识符开头,因此这串可以是稍后由另一个应用程序整体处理。

由于所有记录都具有自动增量 ID,因此我的意图是在此表中在'BEGIN' 和 'END'之间只有'type2' 的记录。

问题是:在这个表中,在“ BEGIN”“END”记录之间,是否有可能出现“type1”的滑动记录?

AFAIK 数据库应该在该事务期间被锁定(默认隔离级别),通常这种行为不应该发生,所以我的实现应该是正确的。这是正确的还是我错过了一些重要的事情?

非常感谢!

4

2 回答 2

2

默认的事务隔离级别是READ COMMITTED——即——你不能读取未修改的未提交数据。这不是表锁,也不能确保一次只能发生一个操作——您通常也不希望它发生。

也许SERIALIZABLE对您的代码来说是一个更好的选择。

http://msdn.microsoft.com/en-us/library/ms173763.aspx

于 2012-09-19T10:42:17.900 回答
2

你忽略了所有重要的细节......

所有这些都会极大地影响答案。

但更重要的是,你在你的陈述中犯了一些非常危险的谬误:

我的意图是在此表中的“开始”和“结束”之间只有“类型 2”的记录。

这种说法没有意义。它使用了一个根本不存在的概念:“表中的记录......之间”。表中的记录不在任何其他记录之前,不在之后,也不在任何其他记录之间。顺序的概念不能应用于表,永远不会。作为一个概念,顺序只存在于结果中,即。在 SELECT 的返回中,并且是未确定的,除非ORDER BY添加了显式子句。因此,您可以重新表述您的问题,因为我想检索由PerformComplexOperation一个原子返回插入的所有记录,而答案是使用适当的键:

  • 为调用生成一个键值
  • 插入的每条记录都使用此键作为列值
  • 检索添加适当的WHERE子句以仅过滤此键

总体而言,您将问题简化到无法理解的程度。而是使用您并不真正了解的概念发布抽象问题,向您发布实际的数据模型模式和实际代码,以及您遇到的问题。

于 2012-09-19T10:47:36.037 回答