ConcurrentModificationExceptionになったTransactionオブジェクトはrollbackが必要か?また、そのまま再利用はできるのか? #appengine

  • ConcurrentModificationExceptionになったTransactionオブジェクトはrollbackは不要
  • 再利用は不可、新規にbeginTransactionが必要。

という訳で上記のエントリーのソースにはトランザクション処理に誤りがありました。

    Key key;
    @Before
    public void setup() throws Exception {
        Counter e = new Counter();
        e.setSeq(new Long(1));
        key = Datastore.put(e);
    }

    @Test
    public void トランザクションのテスト() throws Exception {
        Transaction tx1 = Datastore.beginTransaction();
        Transaction tx2 = Datastore.beginTransaction();
        Counter e1 = Datastore.get(tx1, Counter.class, key);
        Counter e2 = Datastore.get(tx2, Counter.class, key);
        assertThat(e1, is(notNullValue()));
        assertThat(e2, is(notNullValue()));

        e1.setSeq(e1.getSeq() + 1);
        Datastore.put(tx1, e1);
        Datastore.commit(tx1);

        try {
            e2.setSeq(e2.getSeq() + 1);
            Datastore.put(tx2, e2);
            Datastore.commit(tx2);
        } catch (ConcurrentModificationException ignore) {
            assertThat(tx2.isActive(), is(false));
            Transaction tx3 = Datastore.beginTransaction();
            e2 = Datastore.get(tx3, Counter.class, key);
            e2.setSeq(e2.getSeq() + 1);
            Datastore.put(tx3, e2);
            Datastore.commit(tx3);
        }
        assertThat(e2.getSeq(), is(new Long(3)));
    }