gpt4 book ai didi

java - 并发只写事务

转载 作者:行者123 更新时间:2023-11-30 07:18:33 25 4
gpt4 key购买 nike

datastore documentation说:

Upon commiting a transaction for the entity groups, App Engine again checks the last update time for the entity groups used in the transaction. If it has changed since our initial check, App Engine throws an exception

我有三个关于在两个并发事务中执行 new Entity("TestEntity",1) 事务处理数据存储区放置的测试用例。

  • test1:将实体放在第一个事务中,将实体放在第二个事务中,然后提交两个事务。此测试在开发服务器和独立单元测试中运行时通过(即抛出 ConcurrentModificationException),但在生产服务器中运行时失败(即执行时不抛出异常)。

  • test2:将实体放入第一个事务并提交,然后将实体放入第二个事务并提交。这个测试总是失败。

  • 测试 3:尝试在两个事务中获取(不存在的)实体,然后执行测试 2。此测试总是通过抛出 ConcurrentModificationException 来通过。

从这些测试中我得出结论,beginTransactionput 都不能保证执行“初始检查”,我需要支付get 以保证交易的完整性。那是对的吗?

@Test(expected=ConcurrentModificationException.class)
//put1 put2 commit1 commit2
public void test1() {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Transaction txn1 = ds.beginTransaction();
Transaction txn2 = ds.beginTransaction();
ds.put(txn1,new Entity("TestEntity",1));
ds.put(txn2,new Entity("TestEntity",1));
txn1.commit();
txn2.commit();
}

@Test(expected=ConcurrentModificationException.class)
//put1 commit1 put2 commit2
public void test2() {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Transaction txn1 = ds.beginTransaction();
Transaction txn2 = ds.beginTransaction();
ds.put(txn1,new Entity("TestEntity",1));
txn1.commit();
ds.put(txn2,new Entity("TestEntity",1));
txn2.commit();
}

@Test(expected=ConcurrentModificationException.class)
//get1 get2 put1 commit1 put2 commit2
public void test3() throws InterruptedException, ExecutionException {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
ds.delete(KeyFactory.createKey("TestEntity", 1));
Transaction txn1 = ds.beginTransaction();
Transaction txn2 = ds.beginTransaction();
Assert.assertNull(getTestEntity(ds, txn1));
Assert.assertNull(getTestEntity(ds, txn2));
ds.put(txn1,new Entity("TestEntity",1));
txn1.commit();
ds.put(txn2,new Entity("TestEntity",1));
txn2.commit();
}

最佳答案

从某种意义上说,你是对的。 (MVCC) 在事务观察到可变数据快照的第一个事件之前,一致性不需要时间戳。

想一想:在没有任何读取的情况下改变单个记录的事务怎么会违反一致性?由于它没有发出任何读取,因此它基本上不做任何假设。因此,不存在可能会导致写入冲突的假设。

底线是,无论如何,您都可以获得一致性带来的安全优势。在您发出第一个事务读取之前,执行这种一致性不需要时间戳。

关于java - 并发只写事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15285986/

25 4 0
文章推荐: javascript - 确定对象是
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com