MongoDB和System.Transactions

此文为译文,原文地址请点击

如何在你的MongoDB操作使用TransactionScope?

简介
MongoDB是一个开源的NoSQL面向文档的数据库,以JSON格式的动态数据模式,以上是维基百科的描述。这篇文章的目的并不是提供一个高水平的MongoDB 速成课程,但是如果你不知道MongoDB这款华丽的软件,产品网站本身是更好的起点https://www.mongodb.com/what-is-mongodb。
本文档是不仅仅是作为一个C#使用MongoDB的例子,而且它是在一定程度上规范你的CRUD操作。
文档将描述如何建立自己的资源管理类,生成一个可靠的机制操作现有的MongoDB的数据。对我的很多项目都缺乏这个功能,过了一段时间,我决定实现这个功能。我认为解决方案应该满足的3个核心无可争辩的标准:
1.该解决方法不应该是可扩展的。MongoDB来设计这样的可扩展性和部署的问题,超出了本篇文章的范围。在这种情况下,任何解决方案不应该采取违反这个原则MongoDB结构的方式。因此,我需要一个类似的解决方案,促进业务交易和作用作为一种外包装(SiC)而不是作为一个插件。
2.它必须是简单的,在一个范例,是可以接受的,测试,可靠和适合企业需要。没有人愿意学习新的定制的东西,不管是什么甚至更糟的是嵌入到其他的生产环境,特别是当它涉及到作为交易和故障恢复的话题。自定义事务框架解决方案完全排除。
3.我们需要推动我们的数据业务交易,而不是从头开始建立一个交易框架。
鉴于这些边界条件,明显的答案是利用微软已交付的强大和可扩展的功能 .NET 2.0 in System.Transactions namespace。
背景
什么是资源管理器
参与事务的任何资源必须由资源管理器来管理,资源管理器有责任维护其资源的价值变化,并根据事务的结果来允许值更改提交或回滚到原来的结果。微软SQL Server、Oracle数据库、消息队列、内存数据结构定制可以都作为资源管理器。
资源管理器处理持久或不稳定的数据。这种变化是指资源管理器是否支持故障恢复。如果资源管理器支持的耐久性,它存在数据持久存储,如果系统经历了一个失败,死机,停电等,它可以重新恢复交易后,并执行所有必要的行动以完成中断交易。另一方面,不稳定的资源管理者处理他们的数据,如在内存中的数据结构,这意味着在故障恢复中断的交易是不是一个选项了。资源管理器使用,将是本文介绍的重点处理不稳定资源。尽管如此,构建一个可以支持故障恢复的资源管理器,不会远离这篇文章的关键点。所有这些draftly描述动作序列由事务管理器协调。
什么是事务管理器
事务管理是组件,编排的所有资源管理和确保交易将达到终点irrespectably提交或回滚。值得庆幸的是我们没有在这里发展微软给了我们一个很好的选择OOB(记得#决策标准3)。
轻量级的事务管理器(LTM):是一种执行事务管理器使用轻量级事务协议(在本文的范围,谷歌)管理本地事务(单AppDomain)
内核事务管理器(KTM):管理事务性资源的操作系统,文件系统和注册表的当代版本的Windows资源管理器(Vista及以后)。完全与我们的语境无关。
分布式事务协调器(DTC):支持事务的执行。
当我们通过System.Transactions创建事务,总是通过LTM初步处理。虽然我们已经登记的资源管理器只处理挥发性数据或最大的一个持久的单阶段通知资源(单域,没有硬盘的相互作用)的全过程是LTM的监督下。如果我们有更持久的资源,或至少一个资源不支持跨域边界单阶段通知或资源跨越;

MongoDB基本CRUD操作
虽然,正如我已经在介绍,这不是通过C#来使用MongoDB,为以后的使用打下基础。
当我设计一个系统时,我总喜欢在一个系统中建立一个强大的对象层次结构。所以每一个实体的文件,我们要保存我们的MongoDB数据库,将从一个父类包含的信息不多但包括以下:

  public class MongoEntity : IEntity
    {
        [BsonId]
        public string Id { get; set; }
    }

并为每一个集合,我们要在我们的数据库中,我们将创建相应的辅助类,这将使我们能够执行所有的CRUD操作对数据库(基于知识库的模式):

 public interface IEntityRepository<T> where T : IEntity
    {
        IEnumerable<T> All();
        IQueryable<T> All(int page, int pageSize);
        T Get(string id);
        IQueryable<T> GetFunc(Expression<Func<T, bool>> expression);
        T Add(T entity);
        int Add(IEnumerable<T> entities);
        void Remove(T entity);
        bool Remove(string id);
        bool RemoveAll();
        int Remove(Expression<Func<T, bool>> expression);
        T Update(T updatedEntity);
    }

我们为所有未来的数据处理构建了一个抽象类,作为我们的基础类:

 public abstract class EntityRepositoryBase<T> : IEntityRepository<T> where T : IEntity
    {
        private MongoServer m_Server;
        private MongoDatabase m_Index;

        private MongoCollection<T> m_Entities;
        public MongoCollection<T> Entities
        {
            get
            {
                return m_Entities;
            }
        }

        private string m_Collection;

        public EntityRepositoryBase(string collection) : this(collection, null, null)
        {

        }

        public EntityRepositoryBase(string collection, string connectionString, string database)
        {
            m_Collection = collection;
            m_Server = new MongoClient(connectionString).GetServer();
            m_Index = m_Server.GetDatabase(database);
            m_Entities = m_Index.GetCollection<T>(m_Collection);
        }

        public IEnumerable<T> All()
        {
            return this.m_Entities.AsQueryable<T>().ToList();
        }

        public IQueryable<T> All(int page, int pageSize)
        {
            //Out of the scope of this article
        }

        public IEnumerable<D> AllAs<D>()
        {
            return m_Entities.AsQueryable<T>().OfType<D>().ToList();
        }

        public T Get(string id)
        {
            IMongoQuery query = Query.EQ("_id", id);
            return this.m_Entities.Find(query).FirstOrDefault();
        }

        public IQueryable<T> GetFunc(System.Linq.Expressions.Expression<Func<T, bool>> expression)
        {
            return this.m_Entities.AsQueryable<T>().Where(expression);
        }

        public IQueryable<T> GetFunc(System.Linq.Expressions.Expression<Func<T, bool>> expression, int page, int pageSize)
        {
            return this.m_Entities.AsQueryable<T>().Where(expression).Skip((page - 1) * pageSize).Take(pageSize);
        }

        public IQueryable<T> GetAs<D>(System.Linq.Expressions.Expression<Func<T, bool>> expression)
        {
            return m_Entities.FindAllAs<D>().Cast<T>().ToList().AsQueryable().Where(expression);
        }

        public virtual T Add(T entity)
        {
            try
            {
                IEntity oEntity = (entity as IEntity);

                oEntity.Id = String.IsNullOrEmpty(oEntity.Id) ?
                    ObjectId.GenerateNewId().ToString() :
                    oEntity.Id;

                m_Entities.Insert(entity);

                return entity;
            }
            catch (Exception mongoException)
            {
                if (mongoException.HResult == -2146233088)
                {
                    throw new MongoEntityUniqueIndexException("Unique Index violation", mongoException);
                }
                else
                {
                    throw mongoException;
                }
            }

            return default(T);
        }

        public virtual int Add(IEnumerable<T> entities)
        {
            int addCount = 0;

            entities.ToList().ForEach(entity =>
            {
                if (Add(entity) != null)
                {
                    addCount++;
                }
            });

            return addCount;
        }

        public virtual void AddBatch(IEnumerable<T> entities)
        {
            int addCount = 0;

            entities.ToList().ForEach(entity =>
            {
                IEntity oEntity = (entity as IEntity);

                oEntity.Id = String.IsNullOrEmpty(oEntity.Id) ?
                    ObjectId.GenerateNewId().ToString() :
                    oEntity.Id;

                oEntity.Created = timeStamp;
                oEntity.LastModified = timeStamp;
            });

            try
            {
                m_Entities.InsertBatch(entities);
            }
            catch (Exception addBatchException)
            {

            }
        }

        public virtual void Remove(T entity)
        {
            Remove(entity.Id);
        }

        public virtual bool Remove(string id)
        {
            try
            {
                IMongoQuery query = Query.EQ("_id", id);
                var result = m_Entities.Remove(query);
                return result.DocumentsAffected == 1;
            }
            catch (Exception mongoException)
            {
            }

            return false;
        }

        public virtual bool RemoveAll()
        {
            try
            {
                var result = m_Entities.RemoveAll();
                return result.DocumentsAffected == 1;
            }
            catch (Exception mongoException)
            {

            }

            return false;
        }

        public virtual int Remove(System.Linq.Expressions.Expression<Func<T, bool>> expression)
        {
            int removeCount = 0;
            List<T> entitiesToRemove = this.m_Entities.AsQueryable<T>().Where(expression).ToList();

            entitiesToRemove.ForEach(entity =>
            {
                if (Remove((entity as IEntity).Id))
                {
                    removeCount++;
                }
            });

            return removeCount;
        }

        public virtual T Update(T updatedEntity)
        {
            return Update(updatedEntity);
        }

    }

我们已经取得了迄今为止:我们已经创建了一个常见的方式,我们可以发起一个连接到我们的MongoDB数据库进行基本的关键数据操作(不完全摘录如下):

 public EntityRepositoryBase(string collection) : this(collection, null, null)

    public EntityRepositoryBase(string collection, string connectionString, string database)

    public virtual T Add(T entity)

    public virtual void Remove(T entity)

    public virtual T Update(T updatedEntity)

建立事务支持
正如我们之前提到的,资源管理器需要建立来实施事务。这有两个要求。能够保存的值及其变化的资源和继承ienlistmentnotification接口。新建类transactionentity <T>是建立一个单独的类来保持资源的价值,另外还将包含提交和回滚功能。

public class TransactionalEntity<T> where T : IEntity
    {
        private T m_Original;
        public T Original
        {
          get { return m_Original; }
        }

        private T m_Current;
        public T Current
        {
            get { return m_Current; }
        }

        private TransactionalRepositoryBase<T> m_Repository;

        public TransactionalRepositoryBase<T> Repository
        {
            get { return m_Repository; }
        }

        private bool m_CommitWithSuccess = false;

        public bool CommitWithSuccess
        {
            get { return m_CommitWithSuccess; }
        }

        private bool m_RollbackWithSuccess = false;

        public bool RollbackWithSuccess
        {
            get { return m_RollbackWithSuccess; }
        }

        private bool m_Prepared = false;

        public bool Prepared
        {
            get { return m_Prepared; }
        }

        private EntityRepositoryCommandsEnum m_Command;

        public EntityRepositoryCommandsEnum Command
        {
            get { return m_Command; }
        }

        public TransactionalEntity(T original, T current, TransactionalRepositoryBase<T> repository, EntityRepositoryCommandsEnum command)
        {
            m_Original = original;
            m_Current = current;
            m_Repository = repository;
            m_Command = command;
        }

        public bool Commit()
        {
            // if it reached that far it means that all are OK, need just to inform
            // resource manager that he can vote for commit

            m_CommitWithSuccess = true;
            return m_CommitWithSuccess;
        }

        public bool Rollback()
        {
            if (m_Command == EntityRepositoryCommandsEnum.Update)
            {
                m_Repository.NonTxUpdate(this.m_Original);
            }

            if (m_Command == EntityRepositoryCommandsEnum.Add)
            {
                m_Repository.NonTxRemove(this.m_Current);
            }

            if (m_Command == EntityRepositoryCommandsEnum.Remove)
            {
                m_Repository.NonTxAdd(this.m_Original);
            }

            m_RollbackWithSuccess = true;
            return m_RollbackWithSuccess;
        }

        public T Add()
        {
            T result = m_Repository.NonTxAdd(this.m_Current);
            m_Prepared = true;

            return result;
        }

        public void Remove()
        {
            m_Repository.NonTxRemove(this.Original);
            m_Prepared = true;
        }

        public T Update()
        {
            T result =  m_Repository.NonTxUpdate(this.m_Current);
            m_Prepared = true;

            return result;
        }
    }

transactionentity <T>将泛型类,以作为一个参数的认同。它将在各自的属性中存储当前和原始值,它将知道它必须使用的知识库类,以便在数据库中执行操作。此外,通过属性的命令,它将自我意识的命令执行:

 public T Original

    public T Current

    public TransactionalEntity(T original, T current, TransactionalRepositoryBase<T> repository, EntityRepositoryCommandsEnum command)

    public EntityRepositoryCommandsEnum Command

该命令是有限的,是枚举的一部分:

  public enum EntityRepositoryCommandsEnum
    {
        Add,
        Remove,
        Update
    }

另外还有5个重要的方法。提交和回滚,它将代表资源管理器(在所有的投票都是投下和事务管理器的结果来决定这项事务的结果)。根据对数据库的请求的命令,回滚方法决定什么是补偿对策。

 public bool Commit()
        {
            m_CommitWithSuccess = true;
            return m_CommitWithSuccess;
        }

        public bool Rollback()
        {
            if (m_Command == EntityRepositoryCommandsEnum.Update)
            {
                m_Repository.NonTxUpdate(this.m_Original);
            }

            if (m_Command == EntityRepositoryCommandsEnum.Add)
            {
                m_Repository.NonTxRemove(this.m_Current);
            }

            if (m_Command == EntityRepositoryCommandsEnum.Remove)
            {
                m_Repository.NonTxAdd(this.m_Original);
            }

            m_RollbackWithSuccess = true;
            return m_RollbackWithSuccess;
        }

这些剩下的3种方法,添加,更新和删除,这是在做实际工作发布单阶段提交对数据库的操作。他们在调用相关的知识库类的代表,我们将在后面的文章中讨论。

   public T Add()
        {
            T result = m_Repository.NonTxAdd(this.m_Current);
            m_Prepared = true;

            return result;
        }

        public void Remove()
        {
            m_Repository.NonTxRemove(this.Original);
            m_Prepared = true;
        }

        public T Update()
        {
            T result =  m_Repository.NonTxUpdate(this.m_Current);
            m_Prepared = true;

            return result;
        }

下一个类的是最终期待已久的资源管理器。

 public class MongoResourceManager<T> : IEnlistmentNotification where T : IEntity
    {
        private TransactionalEntity<T> m_TxEntity;

        public MongoResourceManager(TransactionalEntity<T> txEntity)
        {
            m_TxEntity = txEntity;
        }

        public MongoResourceManager(T entity, TransactionalRepositoryBase<T> repository, EntityRepositoryCommandsEnum command)
        {
            T current = entity;
            T original = repository.Get(entity.Id);

            TransactionalEntity<T> txEntity = new TransactionalEntity<T>(original, current, repository, command);

            m_TxEntity = txEntity;
        }

        public void Commit(Enlistment enlistment)
        {
            bool success = this.m_TxEntity.Commit();

            if (success)
            {
                enlistment.Done();
            }
        }

        public void InDoubt(Enlistment enlistment)
        {
            Rollback(enlistment);
        }

        public void Prepare(PreparingEnlistment preparingEnlistment)
        {
            if (this.m_TxEntity.Prepared)
            {
                preparingEnlistment.Prepared();
            }
        }

        public void Rollback(Enlistment enlistment)
        {
            bool success = this.m_TxEntity.Rollback();

            if (success)
            {
                enlistment.Done();
            }
        }
    }

为了实现我们的目标,我们必须创建一个新的子类的存储库。这个新的子类transactionalrepositorybase <T>将能够确定是否请求的命令是在事务上下文发布(在一个事务处理是准确的),或者创建一个新的mongoresourcemanager <T>和争取他或执行正常操作对数据库:

public abstract class TransactionalRepositoryBase<T> : EntityRepositoryBase<T> where T : IEntity
    {
        internal delegate T AddEntityHandler(T entity);
        internal delegate void RemoveEntityHandler(T entity);
        internal delegate T UpdateEntityHandler(T entity);

        internal AddEntityHandler NonTxAdd;
        internal RemoveEntityHandler NonTxRemove;
        internal UpdateEntityHandler NonTxUpdate;

        public TransactionalRepositoryBase(string collection) : this(collection, null, null)
        {
        }

        public TransactionalRepositoryBase(string collection, string connectionString, string database) : base(collection, connectionString, database)
        {
            NonTxAdd = new AddEntityHandler(base.Add);
            NonTxRemove = new RemoveEntityHandler(base.Remove);
            NonTxUpdate = new UpdateEntityHandler(base.Update);
        }

        public override T Add(T entity)
        {
            if (Transaction.Current != null)
            {
                TransactionalEntity<T> txEntity = new TransactionalEntity<T>(default(T), entity, this, EntityRepositoryCommandsEnum.Add);
                MongoResourceManager<T> txRm = new MongoResourceManager<T>(txEntity);

                Transaction.Current.EnlistVolatile(txRm, EnlistmentOptions.None);
                return txEntity.Add();
            }
            else
            {
                return NonTxAdd(entity);
            }
        }

        public override void Remove(T entity)
        {
            if (Transaction.Current != null)
            {
                TransactionalEntity<T> txEntity = new TransactionalEntity<T>(entity, default(T), this, EntityRepositoryCommandsEnum.Remove);
                MongoResourceManager<T> txRm = new MongoResourceManager<T>(txEntity);

                Transaction.Current.EnlistVolatile(txRm, EnlistmentOptions.None);
                txEntity.Remove();
            }
            else
            {
                NonTxRemove(entity);
            }
        }

        public override T Update(T entity)
        {
            if (Transaction.Current != null)
            {
                T original = this.Get(entity.Id);
                TransactionalEntity<T> txEntity = new TransactionalEntity<T>(original, entity, this, EntityRepositoryCommandsEnum.Remove);
                MongoResourceManager<T> txRm = new MongoResourceManager<T>(txEntity);

                Transaction.Current.EnlistVolatile(txRm, EnlistmentOptions.None);
                return txEntity.Update();
            }
            else
            {
                return NonTxUpdate(entity);
            }
        }
    }

实现这一点的关键是要重写的添加,更新和删除方法的原始存储库抽象类如下。通过检查交易。当前属性可以确定如果我们在TransactionScope上下文。我们创造了我们transactionalentity <T>及其mongoresourcemanager <T>最后我们得到它的挥发性和我们执行的方法(添加、删除或更新)从transactionalentity <T>类提供。否则,我们将执行一个委托

 public override T Add(T entity)
        {
            if (Transaction.Current != null)
            {
                TransactionalEntity<T> txEntity = new TransactionalEntity<T>(default(T), entity, this, EntityRepositoryCommandsEnum.Add);
                MongoResourceManager<T> txRm = new MongoResourceManager<T>(txEntity);

                Transaction.Current.EnlistVolatile(txRm, EnlistmentOptions.None);
                return txEntity.Add();
            }
            else
            {
                return NonTxAdd(entity);
            }
        }

这些代表都指向添加、删除和更新基类的方法(entityrepositorybase)将执行命令对数据库在单阶段提交。他们将利用从transactionalrepositorybase <T>和transactionalentity <T>。

 internal delegate T AddEntityHandler(T entity);
        internal delegate void RemoveEntityHandler(T entity);
        internal delegate T UpdateEntityHandler(T entity);  

        internal AddEntityHandler NonTxAdd;
        internal RemoveEntityHandler NonTxRemove;
        internal UpdateEntityHandler NonTxUpdate;  

        public TransactionalRepositoryBase(string collection, string connectionString, string database) : base(collection, connectionString, database)
        {
              NonTxAdd = new AddEntityHandler(base.Add);
              NonTxRemove = new RemoveEntityHandler(base.Remove);
              NonTxUpdate = new UpdateEntityHandler(base.Update);
        }

使用实例
让我们创建一个新的实体和一个新的知识库类:

 public class TestDocument : MongoEntity
    {
        public string DocumentId { get; set; }
    }

    public class TestDocumentsRepository : TransactionalRepositoryBase<TestDocument>
    {
        public TestDocumentsRepository()
            : base("test_documents", "mongodb://localhost:27017", "tx_tests")
        {

        }
    }

然后让我们创建一个可以模拟随机成功和中止交易的情况。每一次的仓库。添加(文件)的方法被称为新一mongoresourcemanager创建和加入我们的事务处理范围内创建的交易。如果代码管理达到直到范围。complete()那么事务成功提交否则自动回滚和移除集合中的所有数据。

  private void ExecuteInTx(object sender, EventArgs e)
        {
            TestDocumentsRepository repository = new TestDocumentsRepository();
            repository.RemoveAll();

            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
            {
                try
                {
                    for (int docIdx = 0; docIdx < 5; docIdx++)
                    {
                        int poison = random.Next(1000);

                        if (poison != 0 && poison % 200 == 0)
                        {
                            throw new Exception("Poison killed my TX");
                        }

                        TestDocument document = new TestDocument();
                        document.DocumentId = Guid.NewGuid().ToString();

                        repository.Add(document);

                        Thread.Sleep(100);
                    }

                    scope.Complete();
                }
                catch (Exception)
                {

                }
            }
        }

兴趣点
监控你所要做的只是打开你的Windows组件服务MMC LTM或直接转矩控制的活动:

在这篇文章中所提出的代码绝不是你的产品需求的复制粘贴样本。这是一个引导和基线怎么合并交易在MongoDB数据库。.NET通用方法。

链接: http://pan.baidu.com/s/1slADTAP 密码: nus6

时间: 2024-10-26 23:39:20

MongoDB和System.Transactions的相关文章

C#高级编程 25.5 System.Transactions学习笔记

在.NET 1.x中,基本上是通过ADO.NET实现对不同数据库访问的事务..NET 2.0增加了System.Transactions名称空间,为.NET应用程序带来了一个新的事务变成模型. 所有的事务组件或者类型均定义在System.Transactions程序集中的System.Transactions命名空间下,我们直接称基于此的事务为System.Transactions事务. System.Transactions事务变成模型使我们可以显式(通过System.Transactions

使用 System.Transactions 进行事物管理

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Transactions; namespace DTcms.Web.aspx.main { public partial class test : System.Web.UI.Page { pro

谈谈分布式事务之三: System.Transactions事务详解[上篇]

在.NET 1.x中,我们基本是通过ADO.NET实现对不同数据库访问的事务..NET 2.0为了带来了全新的事务编程模式,由于所有事务组件或者类型均定义在System.Transactions程序集中的System.Transactions命名空间下,我们直接称基于此的事务为System.Transactions事务.System.Transactions事务编程模型使我们可以显式(通过System.Transactions.Transaction)或者隐式(基于System.Transact

谈谈分布式事务之三: System.Transactions事务详解[下篇]

在前面一篇给出的Transaction的定义中,信息的读者应该看到了一个叫做DepedentClone的方法.该方法对用于创建基于现有Transaction对 象的“依赖事务(DependentTransaction)”.不像可提交事务是一个独立的事务对象,依赖事务依附于现有的某个事务(可能是可提交事 务,也可能是依赖事务).依赖事务可以帮助我们很容易地编写一些事务型操作,当环境事务不存的时候,可以确保操作在一个独立的事务中执行:当环境事务存在 的时候,则自动加入其中. 一.依赖事务(Depen

System.Transactions 事务超时属性

System.Transactions 有2个超时属性(timeout 与 maxTimeout),可以通过配置文件来进行设置. 1. timeout System.Transactions 默认的timeout值为1分钟,可以通过app.config/web.config/machine.config来进行设置(对于应用中具体的事务还可以通过调用具体对象TransactionScope或CommittableTransaction的构造函数进行设置).以下配置样例代码将其设置为30秒: <co

“System.Transactions.Diagnostics.DiagnosticTrace”的类型初始值设定项引发异常。

今天在项目中用log4net,App.config文件中增加了configSections节点,程序运行报错“System.Transactions.Diagnostics.DiagnosticTrace”. 解决方法: configSections 节点要作为 configuration 节点下的第一个节点. PS:以前遇到过这个问题,想不起来具体怎么解决了,只记得是个节点顺序问题.以后遇上这种冷门问题还是记录一下吧.

System.Transactions事务超时设置

System.Transactions 有2个超时属性(timeout 与 maxTimeout),可以通过配置文件来进行设置. 1. timeout System.Transactions 默认的timeout值为1分钟,可以通过app.config/web.config/machine.config来进行设置(对于应用中具体的事务还可以通过调用具体对象TransactionScope或CommittableTransaction的构造函数进行设置).以下配置样例代码将其设置为30秒: <co

MongoDB十二种最有效的模式设计【转】

持续关注MongoDB博客(https://www.mongodb.com/blog)的同学一定会留意到,技术大牛Daniel Coupal 和 Ken W. Alger ,从 今年 2月17 号开始,在博客上持续发表了 如何在MongoDB中设计数据库模式的方法.截止到今日(4月20号),12种模式设计的方法已全部与读者见面.本人认为,此系列文章,总结的非常全面,很多地方有首创性,涵盖的场景也很多,并且有理论总结,也有案例分析.文中分享的很多知识使人"如听仙乐耳暂明",开卷受益,常读

mongodb 数据库操作--备份 还原 导出 导入

一,mongodump备份数据库 1,常用命令格 1 mongodump -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -o 文件存在路径 如果没有用户谁,可以去掉-u和-p. 如果导出本机的数据库,可以去掉-h. 如果是默认端口,可以去掉--port. 如果想导出所有数据库,可以去掉-d. 2,导出所有数据库 1 2 3 4 5 6 7 8 9 10 [[email protected] mongodb]# mongodump -h 127.0.0.1 -o /hom