MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Kiểm tra @Transactional với Flapdoodle Embedded MongoDB trong Spring Boot

Bạn có thể tìm thông tin về cách tạo bộ bản sao tại đây

Giải pháp Kotlin của tôi:

import com.mongodb.BasicDBList
import com.mongodb.BasicDBObjectBuilder
import com.mongodb.DBObject
import com.mongodb.client.MongoClient
import com.mongodb.client.MongoClients
import com.mongodb.client.MongoCollection
import com.mongodb.client.MongoDatabase
import de.flapdoodle.embed.mongo.MongodExecutable
import de.flapdoodle.embed.mongo.MongodProcess
import de.flapdoodle.embed.mongo.MongodStarter
import de.flapdoodle.embed.mongo.config.MongoCmdOptionsBuilder
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder
import de.flapdoodle.embed.mongo.config.Net
import de.flapdoodle.embed.mongo.distribution.Version
import de.flapdoodle.embed.process.runtime.Network
import org.assertj.core.api.Assertions.assertThat
import org.bson.Document
import org.junit.jupiter.api.Test
import org.springframework.data.mongodb.MongoDatabaseFactory
import org.springframework.data.mongodb.MongoTransactionManager
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory
import org.springframework.test.context.ActiveProfiles
import org.springframework.transaction.TransactionStatus
import org.springframework.transaction.support.TransactionCallbackWithoutResult
import org.springframework.transaction.support.TransactionTemplate
import java.io.IOException


@ActiveProfiles("test")

class EmbeddedMongoDbTransactionTest {
    private val CONNECTION_STRING = "mongodb://%s:%d/"  

    private var node1MongodExe: MongodExecutable? = null
    private var node1Mongod: MongodProcess? = null
    private var mongo: MongoClient? = null
    private var node2MongodExe: MongodExecutable? = null
    private var node2Mongod: MongodProcess? = null

    @Test
    @Throws(IOException::class)
    fun testSmth() {
        val runtime = MongodStarter.getDefaultInstance()
        val node1Port = 57023
        val node2Port = 57024
        try {
            node1MongodExe = runtime.prepare(
                MongodConfigBuilder().version(Version.Main.PRODUCTION)
                    .withLaunchArgument("--replSet", "rs0")
                    .cmdOptions(MongoCmdOptionsBuilder().useNoJournal(false).build())
                    .net(Net(node1Port, Network.localhostIsIPv6())).build()
            )
            node1Mongod = node1MongodExe?.start()
            node2MongodExe = runtime.prepare(
                MongodConfigBuilder().version(Version.Main.PRODUCTION)
                    .withLaunchArgument("--replSet", "rs0")
                    .cmdOptions(MongoCmdOptionsBuilder().useNoJournal(false).build())
                    .net(Net(node2Port, Network.localhostIsIPv6())).build()
            )
            node2Mongod = node2MongodExe?.start()
            mongo = MongoClients.create(CONNECTION_STRING.format("localhost", node1Port))
            val adminDatabase: MongoDatabase = mongo!!.getDatabase("admin")

            val config = Document("_id", "rs0")
            val members = BasicDBList()
            members.add(Document("_id", 0).append("host", "localhost:$node1Port"))
            members.add(Document("_id", 1).append("host", "localhost:$node2Port"))
            config.put("members", members)

            adminDatabase.runCommand(Document("replSetInitiate", config))

            println(">>>>>> wait")
            println(">>>>>>>>" + adminDatabase.runCommand(Document("replSetGetStatus", 1)))
            Thread.sleep(15_000) // without waiting fails with error : 'not master' on server

            val funDb: MongoDatabase = mongo?.getDatabase("fun")!!

            // insert test 1
            val testCollection: MongoCollection<Document> = funDb.getCollection("test")
            println(">>>>>>>> inserting data")
            testCollection.insertOne(Document("fancy", "value"))
            println(">>>>>>>> finding data")
            assertThat(testCollection.find().first()!!.get("fancy")).isEqualTo("value")


            // insert test 2 (with transaction)
            val mongoTemplate = MongoTemplate(mongo!!, "test")

            // Without creating collection in advance fails with error:
            // Cannot create namespace in multi-document transaction
            // (https://stackoverflow.com/questions/52585715/cannot-create-namespace-in-multi-document-transactionmongodb-4-0-spring-data-2)
            mongoTemplate.createCollection("collection")

            val mongoDatabaseFactory: MongoDatabaseFactory = SimpleMongoClientDatabaseFactory(mongo!!, "test")
            val mongoTransactionManager = MongoTransactionManager(mongoDatabaseFactory)

            val transactionTemplate = TransactionTemplate(mongoTransactionManager)

            transactionTemplate.execute(object : TransactionCallbackWithoutResult() {
                override fun doInTransactionWithoutResult(status: TransactionStatus) {
                    val objectToSave = BasicDBObjectBuilder.start()
                        .add("key", "value")
                        .get()

                    // when
                    mongoTemplate.save(objectToSave, "collection")

                    // then
                    assertThat(mongoTemplate.findAll(DBObject::class.java, "collection"))
                        .extracting("key")
                        .containsOnly("value")
                }
            })

            // after transaction
            assertThat(mongoTemplate.findAll(DBObject::class.java, "collection"))
                .extracting("key")
                .containsOnly("value")

        } finally {
            println(">>>>>> shutting down")
            mongo?.close()
            node1MongodExe?.stop()
            node1Mongod?.stop()
            node2MongodExe?.stop()
            node2Mongod?.stop()
        }
    }
}



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Lập mô hình cho lược đồ bạn bè trong mongoose?

  2. Sự khác biệt MongoDB giữa đối tượng DateTime và chuỗi YYYY-MM-DD

  3. Trình điều khiển C ++ Mongo mới:cách xem kiểu và cách lấy giá trị chuỗi

  4. Xây dựng chỉ mục trong MongoDB với trình điều khiển .NET 2.0

  5. Làm cách nào để tính tổng các mảng từ các tài liệu khác nhau trong MongoDB Aggregation?