如何使用Google Drive API同步有冲突的更改

时间:2014-11-04 08:26:38

标签: google-drive-api

我有一个谷歌驱动器应用程序,它将自动保存更改。如果您有两个活动会话,那么它们将相互覆盖。该应用程序支持合并更改,但我无法看到如何安全地将其与驱动器API集成。我考虑过的一些选择:

  1. 版本安全提交

    • 使用google驱动器“仅在驱动器中的当前版本= = X时更新,否则将失败”
    • 如果失败,则获取最新版本,合并并重试

    • 问题:我认为驱动器不支持此功能。以前的API版本使用了etags,但我在当前的文档中没有提到这一点。

  2. 预提交检查

    • 检查当前保存的版本,如果仍然是最新的,保存
    • 否则下载,合并和更新

    • 问题:客户之间明显的竞争条件

  3. 提交后检查

    • 保存新版
    • 如果新版本符合预期:已完成
    • 如果新版本高于预期:下载以前的版本,合并并更新

    • 问题:我不太相信这是安全的。我可以看到多个客户端进入编辑循环。

  4. Google实时api - 字段绑定

    • 使用google rt datamodel替换文件格式

    • 问题:只需要为google-rt重新设计

  5. Google实时api - 文档支持

    • 使用google rt api外部文档支持

    • 问题:我认为这不能解决问题

  6. 我真的想要一种方法来实现#1,但任何建议都会有所帮助。我很高兴客户端之间有一个基本的锁定/切换方案,但我不认为Drive也支持。

2 个答案:

答案 0 :(得分:1)

根据here," If-Match"使用etags仍然有效。不确定它是否适用于数据,但至少它适用于元数据。

答案 1 :(得分:0)

要跟进user1828559的回答,以下Java代码似乎运行良好:

private File updateDriveFile(Drive drive, File file, byte[] data) throws IOException {
    try {
        ByteArrayContent mediaContent = new ByteArrayContent(MIME_TYPE, data);
        Drive.Files.Update update = drive.files().update(file.getId(), file, mediaContent);

        update.getRequestHeaders().setIfMatch(file.getEtag());

        return update.execute();
    }
    catch (GoogleJsonResponseException e) {
        if (isConflictError(e.getDetails())) {
            logger.warn("ETag precondition failed, concurrent modification detected!");
            return null;
        }

        throw e;
    }
}

private boolean isConflictError(GoogleJsonError error) {
    if (error.getCode() == 412) {
        final List<GoogleJsonError.ErrorInfo> errors = error.getErrors();
        if (errors != null && errors.size() == 1) {
            final GoogleJsonError.ErrorInfo errorInfo = errors.get(0);
            if ("header".equals(errorInfo.getLocationType()) &&
                    "If-Match".equals(errorInfo.getLocation()) &&
                    "conditionNotMet".equals(errorInfo.getReason()))
                return true;
        }
    }

    return false;
}