Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.92k stars 3.84k forks source link

transactions Error.... help me.... error message : Transaction numbers are only allowed on a replica set member or mongos #7073

Closed gom3441 closed 6 years ago

gom3441 commented 6 years ago

I had tried transactions. An error occurs when you put options. Brothers find problems .....plz I followed the example here and followed it. http://thecodebarbarian.com/a-node-js-perspective-on-mongodb-4-transactions.html However, an error occurs. I need a transaction.

Delete the option and it will work normally....

this is code

 const mongoose = require('mongoose');
 const uri = 'mongodb://localhost:27017,localhost:27018,localhost:27019/txn';
 await mongoose.connect(uri, { replicaSet: 'rs' });

 await mongoose.connection.dropDatabase();
 const Account = mongoose.model('Account', new mongoose.Schema({
   name: String, balance: Number
 }));

 await Account.create([{ name: 'A', balance: 5 }, { name: 'B', balance: 10 }]);

 await transfer('A', 'B', 4); // Success
 try {
     await transfer('A', 'B', 2);
 } catch (error) {
   error.message;
 }

async function transfer(from, to, amount) {
   const session = await mongoose.startSession();
   session.startTransaction();
   try {
     const opts = { session, new: true }; // <--- !!!!This is a problem option
     const A = await Account.
       findOneAndUpdate({ name: from }, { $inc: { balance: -amount } }, opts); // <------- Error when I put option
    if (A.balance < 0) {
       throw new Error('Insufficient funds: ' + (A.balance + amount));
     }

     const B = await Account.
       findOneAndUpdate({ name: to }, { $inc: { balance: amount } }, opts); // <------- Error when I put option

     await session.commitTransaction();
     session.endSession();
     return { from: A, to: B };
   } catch (error) {
     await session.abortTransaction();
     session.endSession();
    throw error; // Rethrow so calling function sees error
   }
 }

this is error message

  (node:38696) UnhandledPromiseRejectionWarning: MongoError: Transaction numbers are only allowed on a replica set member or mongos
      at G:\nodejs\node\Admin\node_modules\mongodb-core\lib\connection\pool.js:580:63
      at authenticateStragglers (G:\nodejs\node\Admin\node_modules\mongodb-core\lib\connection\pool.js:503:16)
      at Connection.messageHandler (G:\nodejs\node\Admin\node_modules\mongodb-core\lib\connection\pool.js:539:5)
      at emitMessageHandler (G:\nodejs\node\Admin\node_modules\mongodb-core\lib\connection\connection.js:309:10)
      at Socket.<anonymous> (G:\nodejs\node\Admin\node_modules\mongodb-core\lib\connection\connection.js:452:17)
      at Socket.emit (events.js:182:13)
      at addChunk (_stream_readable.js:283:12)
      at readableAddChunk (_stream_readable.js:264:11)
      at Socket.Readable.push (_stream_readable.js:219:10)
      at TCP.onread (net.js:638:20)
  (node:38696) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
  (node:38696) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code
vkarpov15 commented 6 years ago

You must run a MongoDB replica set to use transactions. Check out run-rs for this. Here's Mongoose's official guide to getting started with transactions with more info.

top-kat commented 3 years ago

@vkarpov15 there are no infos about replica sets in the doc that you linked...Is that impossible to use transaction without replica set or installing a global npm dependency ? It is unusable for me to use run-rs because I'am working with electron and cannot install a global npm dependency on the clients machine.

vkarpov15 commented 3 years ago

@sebRomeo you should be able to use run-rs independently of electron. Or you can set up a replica set yourself. Unfortunately, MongoDB currently requires replica sets for transactions.

marvellouschandan commented 10 months ago

https://www.mongodb.com/docs/manual/tutorial/convert-standalone-to-replica-set/

This is how, you'll fix it in a mac:

Start mongo shell

mongosh

Now in mongoshell run below

use admin
db.adminCommand(
   {
      shutdown: 1,
      comment: "Convert to cluster"
   }
)

Now open mongo configuration file

nano /opt/homebrew/etc/mongod.conf

Paste below content

replication:
   replSetName: rs0

Now run below commands:

# Server must have stopped
brew services info mongodb/brew/mongodb-community

# Now restart server
brew services restart mongodb/brew/mongodb-community

# Now open mongoshell
mongosh

Now create replica set

rs.initiate()

# To view the replica set configuration
rs.conf()

# To check the status of the replica set
rs.status()

Done

ishaangupta-YB commented 5 months ago
db.adminCommand( { shutdown: 1, comment: "Convert to cluster" } )
MongoNetworkError: connection 5 to 127.0.0.1:27017 closed

gives this error, tried multiple things but couldn't understand why it is showing connection closed.

ishaangupta-YB commented 5 months ago
db.adminCommand( { shutdown: 1, comment: "Convert to cluster" } )
MongoNetworkError: connection 5 to 127.0.0.1:27017 closed

gives this error, tried multiple things but couldn't understand why it is showing connection closed.

@marvellouschandan

vkarpov15 commented 5 months ago

@ishaangupta-YB you're sending a shutdown command, so the server you're connected to is shutting down, that's why you're getting a connection closed error

shafayeatt1995 commented 5 months ago

Why replica set required? It makes no sense to me and seems this was a blunder on the Mongodb team.

vkarpov15 commented 5 months ago

More info on why replica sets required for transactions here: https://www.mongodb.com/community/forums/t/why-replica-set-is-mandatory-for-transactions-in-mongodb/9533