[ https://issues.apache.org/jira/browse/CASSANDRA-6426?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13836069#comment-13836069 ]
Aleksey Yeschenko edited comment on CASSANDRA-6426 at 12/1/13 5:00 PM: ----------------------------------------------------------------------- bq. Is the doc accurate ? If yes, how can I guarantee the ORDER of my DML statements in a batch ? The doc is incomplete - you can't specify a top-level timestamp AND timestamps for some of the included statements. You can specify a timestamp per-statement if you don't set the batch-level one. I'll ping the doc team to correct this. was (Author: iamaleksey): bq. Is the doc accurate ? If yes, how can I guarantee the ORDER of my DML statements in a batch ? The doc is out of date. You can specify a timestamp per-statement. I'll ping the doc team to correct this. > Lost update in Prepared statement batch when a column is inserted with null > value in the same batch just before > --------------------------------------------------------------------------------------------------------------- > > Key: CASSANDRA-6426 > URL: https://issues.apache.org/jira/browse/CASSANDRA-6426 > Project: Cassandra > Issue Type: Bug > Components: Core > Environment: Cassandra Server 2.0.3 > Java Driver Core 2.0.0-rc1 > Reporter: DOAN DuyHai > > {panel:title=Test environment} > Cassandra Server *2.0.3* > Java Driver Core *2.0.0-rc1* > {panel} > While implementing batched prepared statements for Achilles, I ran into a > very annoying bug. > {code:title=FailingUnitTest.java|borderStyle=solid} > //Given > Long id = RandomUtils.nextLong(); > session.execute("CREATE TABLE test(id bigint, name text,label text, PRIMARY > KEY(id))"); > PreparedStatement insertPS = session.prepare("INSERT INTO test(id,name,label) > VALUES (?,?,?)"); > PreparedStatement updatePS = session.prepare("UPDATE test SET label=? WHERE > id=?"); > // Notice the "label" column is inserted first with null > BoundStatement insertBS = insertPS.bind(id, "myName", null); > // Then "label" is updated to "myLabel" > BoundStatement updateBS = updatePS.bind("myLabel", id); > //When > BatchStatement batch = new BatchStatement(); > batch.add(insertBS); > batch.add(updateBS); > session.execute(batch); > //Then > Statement statement = new SimpleStatement("SELECT * from test where id=" + > id); > Row row = session.execute(statement).one(); > // Assertion FAIL, "label" is NULL > assertThat(row.getString("label")).isEqualTo("myLabel"); > {code} > The above code always fails. > Even if I switch the order of the bound statements, e.g. *updateBS* added to > the batch before *insertBS*, the test still fails. > {code:title=WorkingUnitTest.java|borderStyle=solid} > //Given > Long id = RandomUtils.nextLong(); > session.execute("CREATE TABLE test(id bigint, name text,label text, PRIMARY > KEY(id))"); > PreparedStatement insertPS = session.prepare("INSERT INTO test(id,name) > VALUES (?,?)"); > PreparedStatement updatePS = session.prepare("UPDATE test SET label=? WHERE > id=?"); > // Notice the "label" column is removed from the insert statement > BoundStatement insertBS = insertPS.bind(id, "myName"); > BoundStatement updateBS = updatePS.bind("myLabel", id); > //When > BatchStatement batch = new BatchStatement(); > batch.add(updateBS); > batch.add(insertBS); > session.execute(batch); > //Then > Statement statement = new SimpleStatement("SELECT * from test where id=" + > id); > Row row = session.execute(statement).one(); > // Assertion SUCCEEDS here > assertThat(row.getString("label")).isEqualTo("myLabel"); > {code} > Only removing column "label" from the first insert bound statement can make > the test succeed. This is pretty annoying. > The rationale for inserting null values is that in Achilles I prepare > generic insert statements for all entities and setting NULL when the field is > not filled at runtime. > Currently, there is no guarantee for batch of prepared statement to be > executed in the order they are declared. -- This message was sent by Atlassian JIRA (v6.1#6144)