12、MongoDB实战:SpringBoot集成MongoDB事务

MongoDB4.0的出现被认为是业界最好的处理事务的文档类型的非关系型的数据库。单节点mongo是不支持事务的。MongoDB单机方式运行不支持事务,需要把单机转为只有一个实例的副本集。

MongoDB4.0保留了对数据库事务的支持。并且还支持跨文档的事务的支持。就是在同一个事务中可以支持对多个文档的操作。这个特点对于业务逻辑比较复杂的需求,可以很大程度的降低代码的复杂度。

一:事务

1.1 pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

1.2 application.yml

uri: 要配置主节点的信息,replicaSet表示副本集名称。
注意:Spring Boot集成MongoDB事务 必须要使用MongoDB副本集,单节点是不支持事务的。

spring:
  data:
    mongodb:
      uri: mongodb://mongo:123456@localhost:27000,localhost:27001/test?connect=replicaSet&replicaSet=rs
#      host: localhost
#      port: 27017
#      database: test
#      username: mongo
#      password: '123456'

mongodb://[username:password@]host1[:port1][,host2[:port2]] [/[database][?options]]

  • mongodb:// 这是固定的格式,必须要指定。
  • username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登陆这个
    数据库
  • host1 必须的指定至少一个host, host1 是这个URI唯一要填写的。它指定了要连接服务器的地
    址。如果要连接复制集,请指定多个主机地址。
  • portX 可选的指定端口,如果不填,默认为27017
  • /database 如果指定username:password@,连接并验证登陆指定数据库。若不指定,默认打开
    test 数据库。
  • ?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对
    name=value,键值对之间通过&或;

*

  • slaveOk=true:开启副本节点读的功能,可实现读写分离。
  • connect=replicaSet:自动到副本集中选择读写的主机。如果slaveOK是打开的,则实现了读写分
  • replicaSet=rs:副本集名称

1.3 Configuration

@Configuration
public class TransactionConfig {
   
     

    @Bean
    public MongoTransactionManager transactionManager(MongoDatabaseFactory factory){
   
     
        return new MongoTransactionManager(factory);
    }
}

1.4 Service

注意:方法上需要使用事务注解 @Transactional。

@Service
public class UserService {
   
     

    @Autowired
    private MongoTemplate mongoTemplate;
    @Transactional
    public void testMongoDBTransactional() {
   
     
        Address shanghai = new Address("shanghai", "pudong");
        Address beijing = new Address("beijing", "chaoyang");
        mongoTemplate.save(shanghai, "address");
        System.out.println(1/0);
        mongoTemplate.save(beijing, "address");
    }
}

1.5 test

@SpringBootTest
@RunWith(SpringRunner.class)
class SpringbootMongodbApplicationTests {
   
     

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserService userService;

    @Test
    void testMongoDBTransactional() {
   
     
        userService.testMongoDBTransactional();
    }
}    

*

二:读写分离

读写分离需要配置slaveOk=true。

spring:
  data:
    mongodb:
      uri: mongodb://mongo:123456@localhost:27000,localhost:27001/test?connect=replicaSet&slaveOk=true&replicaSet=rs

事务的读操作必须在主节点上,所以事务不能进行读写分离。同时开启读写分离又使用事务,事务中涉及到读操作就会报错“Read preference in a transaction must be primary”。

@Service
public class UserService {
   
     

    @Autowired
    private MongoTemplate mongoTemplate;
	// @Transactional
    public void testMongoDBTransactional() {
   
     
        Address shanghai = new Address("shanghai", "pudong");
        Address beijing = new Address("beijing", "chaoyang");
        mongoTemplate.save(shanghai, "address");
        mongoTemplate.save(beijing, "address");

        List<Address> all = mongoTemplate.findAll(Address.class);
        System.out.println(all);
    }
}

*

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: