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

时间:2018-02-08 04:56:07

标签: c# multithreading tcplistener

目前我正在研究C#项目,它基本上是一个基于TCP / Socket的服务器,它运行在专用的IP和端口上。此服务器可能每秒接收1000个请求,并且每个请求都需要在Oracle DB中运行许多SELECT,UPDATE和INSERT查询。所以为了友好地处理这种情况,我已经做了以下事情:

  1. 使其成为多线程(每个请求都在另一个线程中受理)

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

  3. 以上两个步骤极大地改善了服务器响应时间。

    质询/问题: 由于每个线程执行许多DB UPDATE / INSERT,因此为了维护数据完整性,这些活动必须在事务范围内。

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

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

    问题: 有没有办法使用静态数据库连接开始/提交事务,或者我必须退出在服务器启动开始时打开连接的想法,这显然会严重影响性能,因为每秒连接将打开和关闭1000次。 / p>

    您的专家意见将受到高度赞赏。

1 个答案:

答案 0 :(得分:3)

这种方法无法正常工作 - 您需要为每个线程使用单独的连接。 SqlConnection并非设计为由多个线程使用。

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

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

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