-
Notifications
You must be signed in to change notification settings - Fork 405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
无法回滚事务 #77
Comments
你指的是操作单条文档的事务,还是操作多条文档的事务。 |
系统环境、相关软件版本; |
在MongoDB中,对单个文档的操作是原子的。由于您可以使用嵌入式文档和数组来捕获单个文档结构中数据之间的关系,而不是跨多个文档和集合进行规范化,因此这种单文档原子性消除了许多实际用例对多文档事务的需求。 |
https://www.mongodb.com/docs/v7.0/core/transactions-production-consideration/ 必须要用复制集或者分片集群才能使用事务,否则可能导致意料之外的结果 |
单机测试环境:我写了一个测试用例。 package com.zfoo.orm.transaction;
import com.mongodb.client.*;
import com.zfoo.orm.OrmContext;
import com.zfoo.orm.entity.UserEntity;
import org.bson.Document;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TransactionTest {
@Test
public void test() {
var user = new UserEntity();
user.setId(1000L);
user.setC(1);
user.setE("User");
MongoClient myClient = MongoClients.create("mongodb://127.0.0.1:27017/admin");
MongoDatabase database = myClient.getDatabase("test");
String dbInfo = database.runCommand(new Document("buildInfo", 1)).getString("version");
System.out.println("数据库版本:" + dbInfo);
MongoCollection<UserEntity> myCollection = database.getCollection("user", UserEntity.class);
database.drop();
assert 0 == myCollection.countDocuments();
ClientSession mySession = myClient.startSession();
try {
myClient.startSession().withTransaction(() -> {
myCollection.insertOne(user);
//ID重复失败
myCollection.insertOne(user);
return true;
});
} catch (Exception e) {
System.out.println("-----My rollback-----");
mySession.close();
assert 0 == myCollection.countDocuments();
System.out.println("My rollback success");
}
new ClassPathXmlApplicationContext("application.xml");
MongoClient yourClient = OrmContext.getOrmManager().mongoClient();
ClientSession yourSession = yourClient.startSession();
try {
yourClient.startSession().withTransaction(() -> {
OrmContext.getAccessor().insert(user);
OrmContext.getAccessor().insert(user);
return true;
});
} catch (Exception e) {
System.out.println("-----your rollback-----");
yourSession.close();
UserEntity userEntity = OrmContext.getAccessor().load(1000, UserEntity.class);
System.out.println("userEntity:" + userEntity);
assert null == userEntity;
System.out.println("your rollback success");
}
}
} 输出的log如下: 2023-10-17 15:51:42 [ INFO] [main] org.mongodb.driver.client.info(SLF4JLogger.java:71) - MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync", "version": "4.10.2"}, "os": {"type": "Windows", "name": "Windows Server 2022", "architecture": "amd64", "version": "10.0"}, "platform": "Java/Oracle Corporation/21+35-2513"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, streamFactoryFactory=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@626abbd0, com.mongodb.Jep395RecordCodecProvider@169bb4dd, com.mongodb.KotlinCodecProvider@1f9e9475]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[127.0.0.1:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='30000 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, sendBufferSize=0}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, sendBufferSize=0}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=UNSPECIFIED, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null} 数据库版本:6.0.11-rc0-----My rollback-----My rollback success2023-10-17 15:51:43 [ INFO] [main] org.mongodb.driver.client.info(SLF4JLogger.java:71) - MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync", "version": "4.10.2"}, "os": {"type": "Windows", "name": "Windows Server 2022", "architecture": "amd64", "version": "10.0"}, "platform": "Java/Oracle Corporation/21+35-2513"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, streamFactoryFactory=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@626abbd0, com.mongodb.Jep395RecordCodecProvider@169bb4dd, com.mongodb.KotlinCodecProvider@1f9e9475]}, ProvidersCodecRegistry{codecProviders=[org.bson.codecs.pojo.PojoCodecProvider@460b6d54]}]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[127.0.0.1:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='30000 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, sendBufferSize=0}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, sendBufferSize=0}, connectionPoolSettings=ConnectionPoolSettings{maxSize=33, minSize=1, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=UNSPECIFIED, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null} -----your rollback-----userEntity:UserEntity{id=1000, a=0, b=0, c=1, d=false, e='User', f='null', l=null}java.lang.AssertionError |
参考下面的标准写法,只能用Document |
那不就没用ORM了,这种写法确实取不到数据,至少能回滚。是不是初始化client的参数有问题才导致无法回滚? |
弄个副本集再看看事务,单机看不出来 |
使用OrmContext提供的MongoClient无法回滚事务,自行创建的client可以回滚
The text was updated successfully, but these errors were encountered: