首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在c# (驱动器rversion 2.7+)中启动一个事务,在事务持续期间,整个数据库将被锁定,如何修复它?

在c# (驱动器rversion 2.7+)中启动一个事务,在事务持续期间,整个数据库将被锁定,如何修复它?
EN

Stack Overflow用户
提问于 2019-06-24 02:37:16
回答 1查看 239关注 0票数 2

(更新于2019-7-2) 7天后,我终于解决了这个问题.好吧,我的代码没问题,WTF,浪费了很多时间。问题是我的团队使用AliCloud(像亚马逊、Azure这样的中国公司),而Mongodb有很多版本,我们一年前创建了DataBase,该版本将在处理集群操作时锁定数据库。

如果你有什么问题,希望我的经验能帮上忙。

原谅我糟糕的英语..。

dev环境:带有3节点的mongodb4.0集群,支持事务。.net核心2.2 (mongodb驱动程序2.7.2+)机器人3T(单神工具)

MongoDB数据库在启动事务后60秒将被锁定,我想问题可能是锁级别,但我已经尝试过所有的重新关注或写文件,没有任何帮助。

这是一张图片:现在数据库被锁定了,我不能在机器人3T中查询数据,我的web应用程序也不能查询。

我的意思是,在提交事务/中止事务之前,数据库将被锁定。如果这是一个大的,在30多年内完成的,实际上这个read应用程序无法读取其他访问者的数据响应。

事实上,我的webapp的用户总是说,为什么您的应用程序运行速度这么慢,(因为每次超越都会锁定数据库0.xx秒)

代码语言:javascript
复制
TransactionOptions option = new TransactionOptions(readConcern: ReadConcern.Snapshot,writeConcern: WriteConcern.W1);
ClientSessionOptions so =new ClientSessionOptions();
so.DefaultTransactionOptions = option;

var session = _dataBase.Client.StartSession();
var products = _dataBase.GetCollection<Product>("products"); 
var TV = new Product { Description = "Television", SKU = 4001, Price = 2000 };  
session.StartTransaction(option);

try
    { 
      products.InsertOne(session, TV); 
      // after the sentence , database will be locked 

// before commitTransaction, the webapp cannot response, like Robot 3T, // looks like the database is locked
session.CommitTransaction();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-25 02:52:06

我试着用下面的代码复制您正在讨论的那种锁定。但是,在我的本地环境中看不到任何事务的锁定,它使用的是v2.8.1驱动程序和mongodb服务器v4.0.6。您可以在您的环境中运行以下代码并报告输出吗?还请注意代码使用了我的库MongoDB.Entities,所以请先用nuget安装它。

代码语言:javascript
复制
using MongoDB.Entities;
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace StackOverflow
{
    public class Program
    {
        public class Product : Entity
        {
            public string Description { get; set; }
            public double Price { get; set; }
        }

        private static void Main(string[] args)
        {
            new DB("test-transacion-locking", "localhost", 27017);

            (new Product {
                Description = "television",
                Price = 399 }
            ).Save();

            Task.Run(() =>
            {
                using (var TN = new Transaction())
                {
                    var sw1 = new Stopwatch(); sw1.Start();

                    Console.WriteLine("transaction started...");

                    TN.Update<Product>()
                      .Match(p => p.Price == 399)
                      .Modify(p => p.Price, 499)
                      .Modify(p => p.Description, "updated television")
                      .Execute();

                    TN.Save(new Product { Description = "radio", Price = 199 }); ;

                    Task.Delay(10000).Wait(); //wait 10 seconds before commiting

                    TN.Commit();

                    Console.WriteLine($"transaction took: {sw1.Elapsed.TotalSeconds} seconds");
                }
            });

            Task.Delay(10).Wait(); //wait 10 millis to let the transaction begin first

            var sw2 = new Stopwatch(); sw2.Start();

            Console.WriteLine("tv count query started...");

            var tvCount = DB.Queryable<Product>()
                            .Where(p => p.Description.Contains("television"))
                            .Count();

            Console.WriteLine($"found {tvCount} televisions in {sw2.Elapsed.TotalSeconds} seconds");

            Console.ReadKey();
        }
    }
}

这是我的输出:

代码语言:javascript
复制
transaction started...
tv count query started...
found 1 televisions in 0.0986646 seconds
transaction took: 10.1092237 seconds
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56729259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档