【发布时间】:2021-02-15 21:47:19
【问题描述】:
我有一个服务器(很少)动态创建数据库行以适应用户配置的数据模型。在启动期间,服务器可能必须创建大约一千行以及多个插入到现有表中。
完成所有这些后,它会提交事务并向可能正在监听的任何人发送有关新数据模型的通知。问题是,transaction.Commit() 似乎在数据库实际完成更改之前返回,因此如果客户端在发送通知后向服务器发出请求,客户端可能会得到一个空结果。我的假设是等待 transaction.Commit() 将确保事务全部完成并提交。
客户端得到空结果的原因是,当不做 DDL 操作时,数据库正在使用快照隔离,所以很明显快照是在 DDL 操作完成之前拍摄的(但在 transaction.commit 返回之后)
操作顺序为:
- 开始交易
- 在数据库中执行数千次操作 (DDL)
- 提交事务
- 发送有关更改的通知
- 客户端请求数据(快照隔离)
- 没有数据(交易前的状态)返回给客户端。
为什么 transaction.Commit() 在事务完成提交之前完成?如何让服务器等待事务完全完成后再继续发送通知?
编辑:清晰。
【问题讨论】:
-
也许你有一个外部交易同时进行?然后,在外部事务提交之前,您的 Commit 实际上不会应用更改。
-
这当然是一种可能性(这是一个非常成熟的框架,所以不是很容易导航),但我相当肯定它不是这种情况。不过,我会进行调查 - 正如我在下面所写的那样,在我提交后我关闭了连接,因此父事务几乎不会阻塞。如果我们假设情况并非如此,那么这似乎只在涉及 DDL 时才会发生。提交完成后,正常的数据库更新似乎已完全结束。
-
当您说 DDL 时,您是指 CREATE 语句吗? DDL 将使用模式修改锁并阻止其他会话,而不管事务隔离级别如何,所以也许您的意思是 DML(插入)。我建议您运行跟踪以验证事务的顺序。这些症状表明客户端请求 (#5) 在步骤 #1 之前开始的快照事务中完成。
-
我的意思是 DDL - 不在我读过的桌子上。我在一些表中添加列,在其他表中添加行,以便在单个事务中记账。 @Evk 我确实有一个外部 TransactionScope,但是抑制它并不能解决问题。
-
@Evk - 确实是外部 TransactionScope 造成了麻烦!让它成为一个正确的答案,你就会得到一个正确的仪式。
标签: c# sql-server ado.net ddl