忙しい人のための結論(MongoDB 4.1.9版)
docker run --rm --name コンテナ名 -d mongo:4.1.9-bionic mongod --replSet レプリカセット名
docker run --rm mongo:4.1.9-bionic mongo --host コンテナのIPアドレス --eval "rs.initiate({'_id':'レプリカセット名', members:[{_id:0, host:'コンテナのIPアドレス'}]})"
オプションはお好みで。
MongoDBはいいぞ!
MongoDBって便利ですよね。個人的には一番触ってて面白いと思えるDBです。このMongoDB、最近はトランザクションも入って個人のちょっとした用途だったらSQL系のDBとかもういらないんじゃないか、とも思うわけです。大規模な開発だったらSQL系、っていうかAWSのAurora便利すぎだろって感じなんですが。
MongoDBにトランザクションが入ったのはいいのですがレプリカセット構成じゃないと使えないとか制限があって、なんか構築が面倒なので結局SQL系のDBを使っちゃう、なんてことがあるわけです(私のことだ)
実はそんなに面倒でもないのではないか?と思い直し、ここいらで最短構築手順をちゃんと記録して、個人開発ではMongoDBをもっと使っていこう!と思った次第です。
MongoDBをdocker-hubから拾って立ち上げる
それでは、実際にトランザクションが使えるMongoDBを立ち上げてみます。
まずは、MongoDB公式のDockerイメージ置き場
https://hub.docker.com/_/mongo
普通にMongoDBをdocker pullすれば公式イメージが落ちてくるのですが、トランザクションはversion4以降の機能なのでちゃんと新しめのタグで引っ張ってきます。
docker pull mongo:4.1.9-bionic
続いて立ち上げ。公式のHow to use this imageのところに
docker run --name some-mongo -d mongo:tag
と書いてあるのですが、トランザクションはレプリカセット構成でないと使えないわけです。別にレプリカ構成だからって2台以上必要なわけではなく1台でもレプリカセット構成になっていればトランザクションが使えます。
レプリカセットを設定するには、--replSelオプションをつけてmongodを実行すれば良いので、
docker run --name some-mongo -d mongo:tag mongod --replSet レプリカセット名
という形になります。では適当にコンテナ名やレプリカ名をつけて--rmオプションもつけた、実行サンプルです。
docker run --rm --name transaction-mongo -d mongo:4.1.9-bionic mongod --replSet transaction-set
ただし、これだけだとまだ普通に立ち上がるだけです。レプリカセットはrs.initiate()を実行しないと有効になりません。
レプリカの設定を行う
同イメージを使ってmongoコマンドを実行し、コンテナ内のMongoDBでrs.initiate()を実行します。
まずはレプリカがまだ機能していないことを確認。
docker run --rm mongo:4.1.9-bionic mongo --host コンテナのIPアドレス --eval "rs.status()"
レプリカの設定がまだであれば短めのJSONが出力され、次のようなreplsetの設定がないってerrmsgが入ってます。
"errmsg" : "no replset config has been received",
それではレプリカの設定を行います。
docker run --rm mongo:4.1.9-bionic mongo --host コンテナのIPアドレス --eval "rs.initiate({'_id': 'transaction-set', members:[{_id:0, host:'コンテナのIPアドレス'}]})"
再度rs.status()を実行して、設定が正しく行われたことを確認します。errmsgがない長めのJSONが出力されます。
この状態でコンテナのmongoクライアントを実行すると、プロンプトが>ではなくレプリカセット用のプロンプト表示になります。
docker exec -it transaction-mongo mongo
transaction-set:PRIMARY>
プロンプトがレプリカ用のになっているのを確認したら、exitで抜けるなり、そのままコマンドでトランザクションを試して遊ぶなりしてください。
トランザクションAPIの公式ドキュメント
https://docs.mongodb.com/manual/core/transactions/#transactions-api
トランザクションを使うときは、セッションを経由するのを忘れずに
db.コンテナ名.insert()
とかするとトランザクション機能が無視されます。公式ドキュメントのサンプルのように、session.getDatabase()経由でアクセスしないとトランザクションが有効にならないので注意です。
eventsCollection = session.getDatabase("reporting").events;