zoukankan      html  css  js  c++  java
  • MongoDB Transaction 例子

    MongoDB Transaction

    init replset mongodb env

    $mkdir db1 && mkdir db2 && mkdir db3
    $mongod --port 27017 --dbpath ./db --replSet rstest1
    $mongod --port 37017 --dbpath ./db2 --replSet rstest1
    $mongod --port 47017 --dbpath ./db3 --replSet rstest1

    $mongo --port 27017

    rs.initiate( { _id : "rstest1", members: [ { _id: 0, host: "127.0.0.1:27017" }, { _id: 1, host: "127.0.0.1:37017" }, { _id: 1, host: "127.0.0.1:47017" }, ] })

      const mongoose = require('mongoose')
      const mongoUri = 'mongodb://localhost:27017,localhost:37017,localhost:47017/test'
      const client = mongoose.createConnection(mongoUri, { replicaSet: 'rstest' })
      let Acc = client.model('Account', new mongoose.Schema({
          name: String,
          balance: Number
      }))
      async function initTest() {
          await Acc.create({ 'name': 'James', 'balance': 3000 })
          await Acc.create({ 'name': 'Wade', 'balance': 0 })
      }
      async function afterWork() {
          await Acc.remove({ 'name': 'James' })
          await Acc.remove({ 'name': 'Wade' })
      }
      async function transferTest(transfer) {
          let session = await Acc.startSession()
          session.startTransaction()
          try {
              const opts = { session, new: true }
              let a = await Acc.findOneAndUpdate({
                  'name': 'James'
              }, {
                  $inc: { 'balance': -transfer }
              }, opts)
              console.log(a.toObject());
              let b = await Acc.findOneAndUpdate({
                  'name': 'Wade',
              }, {
                  $inc: { 'balance': transfer }
              }, opts)
              console.log(b.toObject());
              await session.commitTransaction()
          } catch (err) {
              session.abortTransaction()
              console.error(err)
          } finally {
              session.endSession()
          }
    
      }
      async function test() {
          await afterWork()
          await initTest()
          await transferTest(100)
              // await afterWork()
      }
      test()
    

    set a debug point or sleep point at

      console.log(a.toObject());
    

    to stop the process
    then run code to read them
    `
    { "_id" : ObjectId("5cb752de57e8791edf030e9d"), "name" : "James", "balance" : 3000, "__v" : 0 }
    { "_id" : ObjectId("5cb752de57e8791edf030e9e"), "name" : "Wade", "balance" : 0, "__v" : 0 }

    `
    it works fine

    then run :
    `
    rstest:PRIMARY> db.accounts.update({"name":"Wade"}, { $inc:{'balance':10}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

    `

    this will return immediately, when the debug point continue, it ran into exception

    null: MongoError: WriteConflict MongoError: Attempted illegal state transition from [TRANSACTION_ABORTED] to [TRANSACTION_ABORTED] ....

    PAY attention

    write concern & read concern

    In MongoDB, clients can see the results of writes before the writes are durable:
    clients using "local" by default can see the result of a write operation before the write operation is acknowledged to the issuing client.
    read isolation

    Thus , in the case of we need to read own writes we need to read concern set "majority", wirte concern "majority"

    how to config this

    further info read-concern

    read-your-own-writes

    read concern : you can disable read concern by setting either:

    • -- enableMajorityReadConcern command line option to false.
    • replication.enableMajorityReadConcern configuration file setting to false

    write concern : your code write-concern option, example :

      const schema = new Schema({ name: String }, {
        writeConcern: {
          w: 'majority',
          j: true
        }
    });
    
    

    more ref

  • 相关阅读:
    JAVA 从一个List里删除包含另一个List的数据
    CentOS 常用命令合集
    010---软链接和硬链接
    009---linux进程管理
    008---vim编辑器
    007---归档、压缩、解压缩
    006---Linux用户、群组和权限
    005---Linux文件与目录管理
    001---Linux系统的启动过程
    002---Linux系统目录结构
  • 原文地址:https://www.cnblogs.com/no7dw/p/13628822.html
Copyright © 2011-2022 走看看