【问题标题】:Using transactions with ADO.NET Data Adapters将事务与 ADO.NET 数据适配器一起使用
【发布时间】:2011-03-04 20:28:15
【问题描述】:

场景:我想让多个(可能是 2 到 20 个)服务器应用程序使用一个使用 ADO.NET 的数据库。我希望单个应用程序能够获得数据库中记录集的所有权,将它们保存在 DataSets 中的内存中(以提高速度),响应客户端对数据的请求,执行更新,并防止其他应用程序在所有权之前更新这些记录已经放弃了。

我是 ADO.NET 的新手,但使用数据适配器(ADO.NET 断开层)的事务似乎应该可以做到这一点。

问题第 1 部分:这是尝试这样做的正确方法吗?

问题第 2 部分:如果这是正确的方法,谁能指出这种方法的任何教程或示例(在 C# 中)?

问题第 3 部分:如果我希望能够获得单个记录的所有权并独立发布它们,我是否需要为每条记录单独事务,并通过扩展单独的 DataAdapter 和DataSet 来保存每条记录,还是有更好的方法来做到这一点?每个应用程序可能同时拥有数千条记录的所有权。

【问题讨论】:

    标签: c# ado.net transactions dataadapter


    【解决方案1】:
    • 您打算将交易保持多长时间?
    • 您要支持多少并发用户?

    这是您需要问自己的两个问题。如果前者的答案是“很长时间”,而后者的答案是“很多”,那么这种方法可能会遇到问题。

    所以,我对第一个问题的回答是:不,这可能不是正确的方法。

    如果您采用事务锁定方法,那么您将限制您的可扩展性和响应时间。您还可能遇到数据库错误。例如SQL Server(假设您使用的是 SQL Server)可能对锁非常贪婪,并且可能锁定比您请求/预期更多的资源。应用程序可以请求一些行级锁来锁定它“拥有”的记录,但是 SQL Server 可以将这些行锁升级为表锁。这会阻塞并可能导致超时或死锁。

    我认为满足您所说的要求的最佳方法是编写一个锁管理器/记录结帐系统。 Martin Fowler 将此称为Pessimistic Offline Lock

    更新

    如果您使用的是 SQL Server 2008,您可以在表级别设置锁升级行为:

    ALTER TABLE T1 SET (LOCK_ESCALATION = DISABLE);

    这将在“大多数”情况下禁用锁升级,并可能对您有所帮助。

    【讨论】:

    • 是的,我正在考虑让交易保持开放很长时间。所有访问数据库的应用程序都是服务器端的。这些应用程序的数量很少,服务于成千上万的客户。记录的所有权只会在服务器应用程序之间不经常迁移。只有在多个服务器应用程序尝试同时访问相同记录的错误情况下。由于这些条件,我希望我可以使用事务来实现悲观并发。不过,您对 SQL Server 贪婪锁定的警告听起来像是一个大问题。
    • @Ergwun:您使用的是 SQL Server 2008 吗?
    • 是的,目前,但我希望让我的应用程序独立于数据提供者。谢谢。
    • +1 感谢悲观离线锁链接和锁升级提示。
    【解决方案2】:

    您实际上需要并发控制以及事务支持。

    Transaction 仅在您对数据库执行多项操作时才会出现。一旦连接被释放,事务就不再适用。

    concurrency 让您可以对同一数据进行多次更新。如果两个或多个客户端持有相同的数据集,并且一个需要在另一个客户端更新数据后读取/写入数据,则并发性将让您决定保留哪一组更新以及忽略哪一组更新。提及并发的概念超出了本文的范围。查看this 文章了解更多信息。

    【讨论】:

    • 我希望使用长事务来实现悲观并发。由于应用程序都是服务器应用程序,我希望这是一个可行的解决方案。
    • 在这种情况下看看 TransactionScope。
    猜你喜欢
    • 2011-05-14
    • 2014-10-02
    • 2011-11-29
    • 2014-09-06
    • 1970-01-01
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多