|
MongoDB does not wait for a response by default when writing to the database. Use the getLastError command to ensure that operations have succeeded. Many of the drivers can invoke the getLastError command automatically on a write operation. Enabling this driver option is called "safe mode" ("write concern" in some drivers). When enabled, the driver piggybacks a getLastError message with each write message. It then awaits the result of the getLastError command before returning. A few other alternative modes of operation exist. First, an application could not call getLastError at all. This might be appropriate if, for example, one is writing data to a log, and would not report the error to the user anyway. Another option would be to only call getLastError after a series of operations. Running in the ShellThe getlasterror command checks for an error on the last database operation for this connection. Since it's a command, there are a few ways to invoke it: > db.$cmd.findOne({getlasterror:1})
Or in the shell: > db.runCommand("getlasterror")
Or you can use the shell helper: > db.getLastError() In the mongo shell, db.getLastError() returns the last error – null if no error. Use db.getLastErrorObj() to see the full error result. db.getLastErrorObj().err should be null if there is no error condition. For more about commands, see the command documentation. When to Usegetlasterror is primarily useful for write operations (although it is set after a command or query too). Write operations by default do not have a return code: this saves the client from waiting for client/server turnarounds during write operations. One can always call getLastError if one wants a return code. If you're writing data to MongoDB on multiple connections, then it can sometimes be important to call getlasterror on one connection to be certain that the data has been committed to the database. For instance, if you're writing to connection #1 and want those writes to be reflected in reads from connection #2, you can assure this by calling getlasterror after writing to connection #1. For maximum speed, skip the getLastError (or "safe mode") for noncritical writes. Use it when you need to confirm to the user that the write succeeded. Optionsjv2.0+: When j:true is specified, the getlasterror call awaits the journal commit before returning. If the server is running without journaling, it returns immediately, and successfully. > db.runCommand({getlasterror:1,j:true})
wA client can block until a write operation has been replicated to N servers. wtimeout may be used in conjunction with w. The default is no timeout (wait forever). > db.getLastError(2, 5000) // w=2, timeout 5000ms
Note the above options can be combined: waiting for journal acknowledgement and acknowledgement that the write has reached a majority of a replica set can make sense. Tagging And MajorityNow with MongoDB 2.0 there is the ability to control which nodes are written to. Instead of specifying the number of nodes which a write must be acknowledged by, you can specify rules based on tags in the configuration. In addition to the tagging rules you can also specify a string of "majority": >db.getLastError("majority") // waits for more than 50% of the configured nodes to acknowledge the write (until replication is applied to the point of that write) fsyncWhen running mongod without journaling (--nojournal), the fsync option forces the database to fsync all files before returning. When running with journaling, the fsync option awaits the next group commit before returning. > db.runCommand({getlasterror:1,fsync:true})
{ "err" : null, "n" : 0, "fsyncFiles" : 2, "ok" : 1 }
Use j, not fsync. CombiningA good combination for highly critical writes is j:true and w:"majority". Return ValueThe return value from the command is an object with various fields. The common fields are listed below; there may also be other fields.
For updates:
With w:<n>/<tag>
Using getLastError from DriversThe drivers support getLastError in the command form and many also offer a "safe" mode for operations. For more on "safe" mode, see each driver's documentation. * C#
Mongo Shell REPL BehaviorThe database shell performs a resetError() before each read/eval/print loop command evaluation - and automatically prints the error, if one occurred, after each evaluation. Thus, after an error, at the shell prompt db.getLastError() will return null. However, if called before returning to the prompt, the result is as one would expect: > try { db.foo.findOne() } catch(e) { print("preverr:" + tojson(db.getPrevError())); print("lasterr:" + tojson(db.getLastError()));} preverr:{"err" : "unauthorized" , "nPrev" : 1 , "ok" : 1} lasterr:"unauthorized" getPrevError CommandWhen performing bulk write operations, resetError() and getPrevError() can be an efficient way to check for success of the operation. For example if we are inserting 1,000 objects in a collection, checking the return code 1,000 times over the network is slow. Instead one might do something like this: db.resetError(); for( loop 1000 times... ) db.foo.save(something...); if( db.getPrevError().err ) print("didn't work!");
See Also |

PLEASE POST QUESTIONS IN THE USER GROUPS FORUM. Post non-question comments and helpful hints here.
blog comments powered by Disqus