多文档事务
mongodb单机只能支持单文档事务,只能保证单文档的原子性,如果想要保证多文档的原子性,那么就需要分布式复制集了,由于我使用的是docker容器创建的mongodb实例,演示的时候也使用docker容器即可。
- 创建三个mongodb实例。
--replSet 设置集群名称
docker run --name mongo1 -p 27017:27017 -d mongo --replSet "RS"
docker run --name mongo2 -p 27018:27017 -d mongo --replSet "RS"
docker run --name mongo3 -p 27019:27017 -d mongo --replSet "RS"
- 在主实例中添加用户并设置权限、用户名和密码。
docker exec -it mongo1 bash;
use admin;
db.createUser(
{
user: "lyra",
pwd: "365373011",
roles: [ { role: "root", db: "admin" } ]
}
)
- 添加spring data mongo的集群配置文件
mongdbUrl格式:mongodb://用户名:密码@实例1ip:实例1端口,实例2ip:实例2端口/数据库?replicaSet=集群名称&replicaSet=认证数据库名称
spring:
# mongodb 连接
data:
mongodb:
uri: mongodb://lyra:[email protected]:27017,192.168.158.222:27018,192.168.158.222:27019/study?replicaSet=RS&authSource=admin
- 在spring data mongo中配置事务管理器。
@Configuration
public class MongoConfig {
@Bean
MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
return new MongoTransactionManager(dbFactory);
}
}
- 在service中添加Transactional注解。
@RestController
public class MongoController {
@Autowired
private MongoTemplate mongoTemplate;
@GetMapping("/test")
@Transactional
public Object test() {
for (int i = 0; i < 10; i++) {
Abc abc = new Abc();
abc.setAge(12);
abc.setName("lyra");
if (i == 5) {
throw new RuntimeException("事务测试");
}
mongoTemplate.insert(abc);
}
return "成功";
}
}
调用接口之后可以看到数据库中的数据并没有进行提交,这表示多文档事务以及配置成功。