使用静态数据库连接 c# 的事务提交和回滚

Transaction Commit and Rollback with Static DB Connection c#

目前我正在开发 C# 项目,它基本上是一个基于 TCP/Socket 的服务器,运行 在专用 IP 和端口上。此服务器每秒可能会收到 1000 个请求,每个请求都需要 SELECT、更新和插入查询的数量 运行 在 Oracle 数据库中。因此,为了友好地处理这种情况,我做了以下工作:

  1. 让它成为多线程(每个请求都在一个单独的线程中处理)

  2. 为了提高性能,我在服务器启动时打开连接并将其分配给静态变量以供每个线程使用它来执行数据库活动,因此每个线程都不需要打开和关闭连接的开销.

以上两个步骤极大地缩短了服务器响应时间。

Challenge/Problem: 由于每个线程都执行许多 DB UPDATE / INSERT,因此为了保持数据完整性,这些活动必须在事务范围内。

我在线程中尝试了 System.Transaction.TransactionScope() 但它根本不起作用,并且在调用 scope.complete() 之前提交了所有 insert/update 查询(不确定但可能是由于在服务器启动时已经打开的数据库连接,换句话说,数据库连接在启动 TransactionScope())

之前打开

我也在线程中尝试了 StaticDBConnection.BeginTransaction(.....),但由于连接是静态的,因此它也会影响其他线程。

问题: 有什么方法可以使用静态数据库连接的 Begin/Commit 事务,或者我不得不放弃在服务器启动开始时打开连接的想法,这显然会对性能产生严重影响,因为每秒将打开和关闭 1000 次连接.

非常感谢您的专家意见。

这不会(正确)以这种方式工作 - 您需要为每个线程使用单独的连接。 SqlConnection 不是为多线程使用而设计的。

但这并不意味着总是会打开每秒 1000 个连接。由于连接池,一旦完成连接(通过调用 CloseDispose) - 连接将返回到池中,下次调用 Open - 来自池的连接(如果可用)将被使用而不是真正打开新的数据库连接。

例如,如果一个请求的数据库工作需要 10 毫秒 - 每秒约 100 个请求可以由同一个 "physical" 数据库连接处理。为此,您需要做的只是创建新的 SqlConnection,打开它,然后像往常一样在完成后关闭(并确保未禁用连接池并且最大池大小适合您的任务)。

对于如此高的请求率,您还可以从异步处理中获益。 Socket可以异步方式接受和处理传入的请求,数据库工作也可以异步进行。这将减少使用中的线程数并提高性能,因为创建和维护线程也不是免费的。通过异步处理请求 - 在 IO 操作(例如等待套接字上的请求或执行数据库查询)期间线程被释放并返回到另一个池(.NET 线程池)等 "busy" 线程数(和总线程数) ) 比你为每个套接字连接使用新线程要少得多。