If you there's no documentation, then what you can do is reverse engineering. So, I've written a couple of scripts to set up MongoDB with transaction and proxy server which observes the commands.
The followings are the scripts I made to investigate:
- https://github.com/ktakashi/r6rs-mongodb/blob/master/tools/proxy.scm
- https://github.com/ktakashi/r6rs-mongodb/blob/master/tools/analyser.sh
- https://github.com/ktakashi/r6rs-mongodb/blob/master/tools/parse-commands.scm
mongo
shell. Then the third one prints wire protocol commands in, sort of, a human-readable format.With this investigation, I've figured out that I need to add
lsid
, txnNumber
, autocommit
and startTransaction
. Okay, I've never seen them on the document, so I have no idea how these options works, but just followed the example. Then, here comes the transaction support.How to use
This is an example of a transaction:
#!r6rs (import (rnrs) (mongodb)) (define conn (make-mongodb-connection "localhost" 27017)) (define collection "txn") (open-mongodb-connection! conn) ;; create the collection a head (mongodb-database-run-command db `(("create" ,collection))) (let* ((session (mongodb-session-start conn)) ;; start session (db (mongodb-session-database session "test"))) ;; create a database with session (guard (e (else (mongodb-session-abort-transaction session))) (mongodb-session-start-transaction! session) ;; start transaction ;; okay insert documents using usual database procedure ;; NB: has to be command, not other procedures... (mongodb-database-insert-command db collection '#((("id" 1) ("foo" "bar")))) (mongodb-database-insert-command db collection '#((("id" 2) ("foo" "bar")))) ;; and commit (mongodb-session-commit-transaction! session)) ;; session must be end (mongodb-session-end! session)) (let* ((db (make-mongodb-database conn "test")) (r (mongodb-database-query db collection '()))) (mongodb-query-result-documents r))I haven't implement any utilities of transaction related procedures. So at this moment, you need to bare with low-level APIs.
How it works
Maybe you don't want to know, but it's nice to mention. When a session is created, then it also creates a session id. Then the database retrieved from the session adds the session id to query messages (OP_QUERY, not OP_MSG). Once
mongodb-session-start-transaction!
procedure is called, then it allocates transaction number and after this, the database also adds transaction information.If the MongoDB server doesn't support the transaction, then the session automatically detects it and doesn't send any session or transaction related command.
And again, I'm not sure if I implemented correctly or not.
Once the official document of the transaction commands is written, I'll come back and review.
No comments:
Post a Comment