在写入SQL Server 2014中的基础表后立即查询视图

mpe*_*eac 10 .net sql sql-server linq-to-sql

我有一个问题,如果我写一个表(使用Linq-to-SQL)这是一个视图的依赖项,然后立即转身查询该视图以检查写入的影响(使用新连接到数据库,因此新的数据上下文),写入的影响不会立即显示,但需要几秒钟才能显示.这种情况偶尔会发生(也许是10-20每次10,000写入一次).

这是视图的定义:

CREATE VIEW [Position].[Transactions]
WITH SCHEMABINDING
AS
(
  SELECT
    Account,
    Book,
    TimeAPIClient AS DateTimeUtc,
    BaseCcy AS Currency,
    ISNULL(QuantityBase, 0) AS Quantity,
    ValueDate AS SettleDate,
    ISNULL(CAST(0 AS tinyint), 0) AS TransactionType
  FROM Trades.FxSpotMF
  WHERE IsCancelled = 0

  UNION ALL

  SELECT
    Account,
    Book,
    TimeAPIClient AS DateTimeUtc,
    QuoteCcy AS Currency,
    ISNULL(-QuantityBase * Rate, 0) AS Quantity,
    ValueDate AS SettleDate,
    ISNULL(CAST(0 AS tinyint), 0) AS TransactionType
  FROM Trades.FxSpotMF
  WHERE IsCancelled = 0

  UNION ALL

  SELECT
    Account,
    Book,
    ExecutionTimeUtc AS DateTimeUtc,
    BaseCcy AS Currency,
    ISNULL(QuantityBase, 0) AS Quantity,
    ValueDate AS SettleDate,
    ISNULL(CAST(1 AS tinyint), 1) AS TransactionType
  FROM Trades.FxSpotManual
  WHERE IsCancelled = 0

  UNION ALL

  SELECT
    Account,
    Book,
    ExecutionTimeUtc AS DateTimeUtc,
    QuoteCcy AS Currency,
    ISNULL(-QuantityBase * Rate, 0) AS Quantity,
    ValueDate AS SettleDate,
    ISNULL(CAST(1 AS tinyint), 1) AS TransactionType
  FROM Trades.FxSpotManual
  WHERE IsCancelled = 0

  UNION ALL

  SELECT
    Account,
    Book,
    ExecutionTimeUtc AS DateTimeUtc,
    BaseCcy AS Currency,
    ISNULL(SpotQuantityBase, 0) AS Quantity,
    SpotValueDate AS SettleDate,
    ISNULL(CAST(2 AS tinyint), 2) AS TransactionType
  FROM Trades.FxSwap

  UNION ALL

  SELECT
    Account,
    Book,
    ExecutionTimeUtc AS DateTimeUtc,
    QuoteCcy AS Currency,
    ISNULL(-SpotQuantityBase * SpotRate, 0) AS Quantity,
    SpotValueDate AS SettleDate,
    ISNULL(CAST(2 AS tinyint), 2) AS TransactionType
  FROM Trades.FxSwap

  UNION ALL

  SELECT
    Account,
    Book,
    ExecutionTimeUtc AS DateTimeUtc,
    BaseCcy AS Currency,
    ISNULL(ForwardQuantityBase, 0) AS Quantity,
    ForwardValueDate AS SettleDate,
    ISNULL(CAST(2 AS tinyint), 2) AS TransactionType
  FROM Trades.FxSwap

  UNION ALL

  SELECT
    Account,
    Book,
    ExecutionTimeUtc AS DateTimeUtc,
    QuoteCcy AS Currency,
    ISNULL(-ForwardQuantityBase * ForwardRate, 0) AS Quantity,
    ForwardValueDate AS SettleDate,
    ISNULL(CAST(2 AS tinyint), 2) AS TransactionType
  FROM Trades.FxSwap

  UNION ALL

  SELECT
    Account,
    c.Book,
    TimeUtc AS DateTimeUtc,
    Currency,
    ISNULL(Amount, 0) AS Quantity,
    SettleDate,
    ISNULL(CAST(3 AS tinyint), 3) AS TransactionType
  FROM Trades.Commission c
  JOIN Trades.Payment p
    ON c.UniquePaymentId = p.UniquePaymentId
    AND c.Book = p.Book
)
Run Code Online (Sandbox Code Playgroud)

而这是由Linq-to-SQL生成的用于写入其中一个基础表的查询:

INSERT INTO [Trades].[FxSpotMF] ([UniqueTradeId], [BaseCcy], [QuoteCcy], [ValueDate], [Rate], [QuantityBase], [Account], [Book], [CounterpartyId], [Counterparty], [ExTradeId], [TimeAPIClient], [TimeAPIServer], [TimeExchange], [TimeHandler], [UniqueOrderId], [IsCancelled], [ClientId], [SequenceId], [ExOrdId], [TradeDate], [OrderCycleId], [CycleIndex])
  VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18, @p19, @p20, @p21, @p22)
Run Code Online (Sandbox Code Playgroud)

这是Linq-to-SQL生成的用于检查写入效果的查询:

SELECT
  SUM([t0].[Quantity]) AS [Item2],
  [t0].[Currency] AS [Item1]
FROM [Position].[Transactions] AS [t0]
WHERE ([t0].[Book] = @p0)
AND ([t0].[DateTimeUtc] < @p1)
GROUP BY [t0].[Currency]
Run Code Online (Sandbox Code Playgroud)

此外,这是生成写入的Linq-to-SQL代码(使用F#类型提供程序):

type Schema = Microsoft.FSharp.Data.TypeProviders.DbmlFile<"TradeDb.dbml", ContextTypeName="TradeDb"> 

use db = new Schema.TradeDb(connectionString)
let trade = new Schema.Trades_FxSpotMF()
(* omitted: set object properties corresponding to column values here... *)
db.Trades_FxSpotMF.InsertOnSubmit(trade)
db.SubmitChanges()
Run Code Online (Sandbox Code Playgroud)

而这是生成读取的相应Linq-to-SQL:

use db = new Schema.TradeDb(connectionString)
query { for t in db.Position_Transactions do
        where ( t.Book = book &&
                t.DateTimeUtc < df.MaxExecutionTimeExcl
              )
        groupBy t.Currency into group
        let total = query { for x in group do sumBy x.Quantity }
        select (group.Key, total)
      }
|> Map.ofSeq
Run Code Online (Sandbox Code Playgroud)

我原以为System.Data.Linq.DataContext.SubmitChanges()只有在写入事务完成后才会返回,并且视图的任何后续查询都必须包含写入的效果...我错过了什么/做错了什么?

mpe*_*eac 3

我终于弄清楚了这一点:数据库写入是在它们自己的线程中完成的,主线程在检查结果之前等待所有写入线程完成。然而,代码中存在一个检查所有线程是否完成的错误,导致主线程过早地进行检查。