1

我使用 Java 使用 Google App Engine,并通过 JPA 使用 Datastore。我想为每个用户保存个人资料图片:

@Entity
public class User implements Serializable {
    @Id
    private String userId;
    private String imageKey; // saves BlobKey.getKeyString()
    // ... other fields and getter/setter methods ...
}

如果用户想要更改他们的个人资料图像,我(应该)更新 imageKey 字段并删除与旧 imageKey 关联的旧图像。

但是,Blobstore for Python 的文档说:

删除 Blobstore 值与数据存储事务分开进行。如果在数据存储事务期间调用该方法,无论事务提交成功还是重试,都会立即生效。

这似乎我不能将更新 imageKey 和删除旧图像作为一个原子操作,它也会影响到 Java。

这是我做这项工作的尝试:

public class Engine implements ServletContextListener {
    private EntityManagerFactory emf;
    private BlobstoreService blobstoreService;

    // Servlet will call getUser, modify returned object, and call updateUser with that object
    public User getUser(final String userId) throws EngineException {
        return doTransaction(new EngineFunc<User>() { // Utility method for create Entity manager and start transaction
            @Override
            public User run(EntityManager em) throws EngineException {
                return em.find(User.class, key);
            }
        });
    }

    public void updateUser(final User user) throws EngineException {
        doTransaction(new EngineFunc<Void>() {      
            @Override
            public Void run(EntityManager em) throws EngineException {
                em.merge(user);
                return null;
            }
        });
        user.purgeOldImages(blobstoreService);
    }

    // ... Other methods ...
}

public class User {
    @Transient
    private transient Set<String> oldImageList = new CopyOnWriteArraySet<>();

    public void setImageKey(String imageKey) {
        if (this.imageKey != null) {
            oldImageList.add(this.imageKey);
        }
        this.imageKey = imageKey;
        if (imageKey != null) {
            oldImageList.remove(imageKey);
        }
    }

    public void purgeOldImages(BlobstoreService blobService) {
        Set<BlobKey> toDelete = new HashSet<>();
        for (String s : oldImageList) {
            toDelete.add(new BlobKey(s));
            oldImageList.remove(s);
        }
        blobService.delete(toDelete.toArray(new BlobKey[0]));
    }

    // ... Other methods ...
}

我认为这既不是“美丽”也不是正确的代码。有正确的方法吗?

4

0 回答 0