如何在Spring Data Mongodb事务期间使用文档锁防止外部修改记录
我有一个关于Spring数据Mongo和Mongo事务的问题 我已经成功地实现了事务,并利用Spring@Transactional注释验证了提交和回滚的工作是否如预期的那样 然而,我很难让事务按照我在Spring数据环境中期望的方式工作 Spring数据执行Mongo->Java对象映射。因此,更新内容的典型模式是从数据库中获取内容,然后进行修改,然后将其保存回数据库。在实现事务之前,我们一直使用Spring的乐观锁定来考虑在获取和更新之间记录发生更新的可能性 我希望,一旦我们能够使用事务,我就能够在所有更新中不包含乐观的锁定基础设施。因此,我希望,在事务的上下文中,获取将创建一个锁,这样我就可以进行更新和保存,并且我将被隔离,这样就没有人可以像以前那样进入并进行更改 但是,根据我所看到的,fetch不会创建任何类型的锁,因此没有任何东西阻止任何其他连接更新记录,这意味着尽管有本机mongodb事务支持,我似乎必须维护所有乐观锁定代码 我知道我可以使用mongodb findAndUpdate方法进行更新,这不允许进行临时修改,但这与将数据加载到Java对象中的Spring数据的标准模式相反。因此,除了能够操作Java对象之外,我还必须在整个应用程序中散布特定于mongo的代码,或者为我想要进行的每种特定类型的更新创建存储库方法 有人对如何在保持仅使用Java对象的Spring数据范例的同时干净地处理这种情况有什么建议吗如何在Spring Data Mongodb事务期间使用文档锁防止外部修改记录,mongodb,spring-data-mongodb,spring-transactions,Mongodb,Spring Data Mongodb,Spring Transactions,我有一个关于Spring数据Mongo和Mongo事务的问题 我已经成功地实现了事务,并利用Spring@Transactional注释验证了提交和回滚的工作是否如预期的那样 然而,我很难让事务按照我在Spring数据环境中期望的方式工作 Spring数据执行Mongo->Java对象映射。因此,更新内容的典型模式是从数据库中获取内容,然后进行修改,然后将其保存回数据库。在实现事务之前,我们一直使用Spring的乐观锁定来考虑在获取和更新之间记录发生更新的可能性 我希望,一旦我们能够使用事务,我
提前谢谢 我找不到任何方法在Spring/MongoDB事务中执行“读取”锁定 但是,为了能够继续使用以下模式:
public class BaseRepositoryImpl<T, ID extends Serializable> extends SimpleMongoRepository<T, ID>
implements BaseRepository<T, ID> {
private final MongoEntityInformation<T, ID> entityInformation;
private final MongoOperations mongoOperations;
public BaseRepositoryImpl(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) {
super(metadata, mongoOperations);
this.entityInformation = metadata;
this.mongoOperations = mongoOperations;
}
public T lockForUpdate(ID id) {
// Verify the class has a version before trying to increment the version in order to lock a record
try {
getEntityClass().getMethod("getVersion");
} catch (NoSuchMethodException e) {
throw new InvalidConfigurationException("Unable to lock record without a version field", e);
}
return mongoOperations.findAndModify(query(where("_id").is(id)),
new Update().inc("version", 1L), new FindAndModifyOptions().returnNew(true), getEntityClass());
}
private Class<T> getEntityClass() {
return entityInformation.getJavaType();
}
}
对于MongoDB事务,如果将获取和更新包装在事务中,则自获取文档以来的任何更改都将导致事务提交抛出WriteConflict。你能解释一下为什么这不是理想的行为吗?或者,也许我在SpringData方面遗漏了一些东西。
Record record = recordRepository.lockForUpdate(recordId);
...make changes to record...
recordRepository.save();