[ 
https://issues.apache.org/jira/browse/CASSANDRA-6426?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13836062#comment-13836062
 ] 

DOAN DuyHai commented on CASSANDRA-6426:
----------------------------------------

@Aleskey

 Thanks a lot for giving the rules!  It's kind of not so obvious and not 
mentionned anywhere.

I've just read the doc for batch statements for C*  2.0, it is said clearly 
that Timestamp can only be set on the batch statement and not on individual DML 
statements inside the batch:

http://www.datastax.com/documentation/cql/3.1/webhelp/index.html#cql/cql_reference/batch_r.html#reference_ds_djf_xdd_xj

{panel}
*Individual DML statements inside a BATCH cannot specify a timestamp.* These 
individual statements can specify a TTL (time to live). TTL columns are 
automatically marked as deleted (with a tombstone) after the requested amount 
of time has expired.
{panel}

 Is the doc accurate ? If yes, how can I guarantee the ORDER of my DML 
statements in a batch ?


> 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)

Reply via email to