Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable implicit pre-read by default for Put operations #1336

Merged
merged 5 commits into from
Dec 1, 2023

Conversation

brfrn169
Copy link
Collaborator

Description

This PR disables implicit pre-read by default for Put operations because the feature is backward incompatible.

Related issues and/or PRs

Changes made

  • Disabled implicit pre-read by default for Put operations
  • Modified related unit tests and integration tests
  • Revised related documents

Checklist

  • I have commented my code, particularly in hard-to-understand areas.
  • I have updated the documentation to reflect the changes.
  • Any remaining open issues linked to this PR are documented and up-to-date (Jira, GitHub, etc.).
  • Tests (unit, integration, etc.) have been added for the changes.
  • My changes generate no new warnings.
  • Any dependent changes in other PRs have been merged and published.

Additional notes (optional)

N/A

Release notes

N/A

{% capture notice--info %}
**Note**

When you update an existing record, you need to read the record by using `Get` or `Scan` before using a `Put` operation. Otherwise, the operation will fail due to a conflict. This occurs because ScalarDB assumes that another transaction wrote the record. Instead of reading the record explicitly, you can enable implicit pre-read. See [Enable implicit pre-read for `Put` operations](#enable-implicit-pre-read-for-put-operations) for details.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise, the operation will fail due to a conflict. This occurs because ScalarDB assumes that another transaction wrote the record

My understanding is as follows

  • ScalarDB needs to detect if another transaction wrote the record (== conflict)
  • Put operation without reading the record will fail since ScalarDB can't check the conflict

If it's correct, there might be room to make the description clearer.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think your understanding is correct. However, since this document is not intended to explain the details of the transaction mechanism in ScalarDB, we might not need to explain it deeply here. Or do you have an idea for this? If yes, can you please suggest it? Thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be a bit deep (so it might not be proper for this document), but how about the following description?

Suggested change
When you update an existing record, you need to read the record by using `Get` or `Scan` before using a `Put` operation. Otherwise, the operation will fail due to a conflict. This occurs because ScalarDB assumes that another transaction wrote the record. Instead of reading the record explicitly, you can enable implicit pre-read. See [Enable implicit pre-read for `Put` operations](#enable-implicit-pre-read-for-put-operations) for details.
When you update an existing record, you need to read the record by using `Get` or `Scan` before using a `Put` operation. Otherwise, the operation will fail due to a conflict. ScalarDB needs to check whether another transaction wrote the record for concurrency control when it runs write operations, but ScalarDB cannot do that if you don't read the existing record before write operations. This causes the conflict error. Instead of reading the record explicitly, you can enable implicit pre-read. See [Enable implicit pre-read for `Put` operations](#enable-implicit-pre-read-for-put-operations) for details.

Or, how about the following simple description? I think this is not a deep.

Suggested change
When you update an existing record, you need to read the record by using `Get` or `Scan` before using a `Put` operation. Otherwise, the operation will fail due to a conflict. This occurs because ScalarDB assumes that another transaction wrote the record. Instead of reading the record explicitly, you can enable implicit pre-read. See [Enable implicit pre-read for `Put` operations](#enable-implicit-pre-read-for-put-operations) for details.
When you update an existing record, you need to read the record by using `Get` or `Scan` before using a `Put` operation. Otherwise, the operation will fail due to a conflict. This occurs because the specification of ScalarDB to manage transactions properly. Instead of reading the record explicitly, you can enable implicit pre-read. See [Enable implicit pre-read for `Put` operations](#enable-implicit-pre-read-for-put-operations) for details.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@komamitsu (CC: @feeblefakie) What do you think about @kota2and3kan's idea?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed Enable implicit pre-read for Put operations already has a detailed description about the background. So, the following simple one is okay?

When you update an existing record, you need to read the record by using `Get` or `Scan` before using a `Put` operation. The implicit pre-read feature would be useful for that. See [Enable implicit pre-read for `Put` operations](#enable-implicit-pre-read-for-put-operations) for details.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you update an existing record, you need to read the record by using Get or Scan before using a Put operation. Otherwise, the operation will fail due to a conflict. This occurs because the specification of ScalarDB to manage transactions properly. Instead of reading the record explicitly, you can enable implicit pre-read. See Enable implicit pre-read for Put operations for details.

This looks simple and users can know the details with Enable implicit pre-read for Put operations.

Only one thing:

This occurs because the specification of ScalarDB to manage transactions properly.

This occurs because of the specification of ScalarDB to manage transactions properly. seems a bit better.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, thank you. Let me fix with This occurs because of the specification of ScalarDB to manage transactions properly. Thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only one thing:

This occurs because the specification of ScalarDB to manage transactions properly.

This occurs because of the specification of ScalarDB to manage transactions properly. seems a bit better.

Ah, sorry... I overlooked the grammar error... 🙇
I fixed my suggestion just in case!

Suggested change
When you update an existing record, you need to read the record by using `Get` or `Scan` before using a `Put` operation. Otherwise, the operation will fail due to a conflict. This occurs because ScalarDB assumes that another transaction wrote the record. Instead of reading the record explicitly, you can enable implicit pre-read. See [Enable implicit pre-read for `Put` operations](#enable-implicit-pre-read-for-put-operations) for details.
When you update an existing record, you need to read the record by using `Get` or `Scan` before using a `Put` operation. Otherwise, the operation will fail due to a conflict. This occurs because of the specification of ScalarDB to manage transactions properly. Instead of reading the record explicitly, you can enable implicit pre-read. See [Enable implicit pre-read for `Put` operations](#enable-implicit-pre-read-for-put-operations) for details.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in dfec35a. Thanks.

.build();
```

Note that if you are certain that a record you are trying to mutate does not exist, you should not enable implicit pre-read for the `Put` operation for better performance. For example, if you load initial data, you should not enable implicit pre-read. A `Put` operation without implicit pre-read is faster than `Put` operation with implicit pre-read because the operation skips an unnecessary read.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, if you load initial data, you should not enable implicit pre-read.

I think load fits a limited situation. insert a new record or something sounds more general?

Copy link
Collaborator Author

@brfrn169 brfrn169 Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think load initial data is an example of the situation where you are certain that a record you are trying to mutate does not exist. insert a new record sounds too general and it's not an example to me. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Your intention sounds reasonable 👍

I just thought "load" sounds to make a target state expected one. Insertions would be mainly used for that, but updates might be used. So, I slightly preferred explicitly mentioning insert. But either sounds okay!

@brfrn169 brfrn169 requested a review from komamitsu November 30, 2023 06:23
Copy link
Contributor

@kota2and3kan kota2and3kan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you!

Copy link
Contributor

@komamitsu komamitsu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

Copy link
Member

@josh-wong josh-wong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! I've added some comments and suggestions. PTAL!

core/src/main/java/com/scalar/db/api/OperationBuilder.java Outdated Show resolved Hide resolved
core/src/main/java/com/scalar/db/api/OperationBuilder.java Outdated Show resolved Hide resolved
core/src/main/java/com/scalar/db/api/OperationBuilder.java Outdated Show resolved Hide resolved
core/src/main/java/com/scalar/db/api/OperationBuilder.java Outdated Show resolved Hide resolved
core/src/main/java/com/scalar/db/api/OperationBuilder.java Outdated Show resolved Hide resolved
core/src/main/java/com/scalar/db/api/OperationBuilder.java Outdated Show resolved Hide resolved
core/src/main/java/com/scalar/db/api/OperationBuilder.java Outdated Show resolved Hide resolved
core/src/main/java/com/scalar/db/api/OperationBuilder.java Outdated Show resolved Hide resolved
docs/api-guide.md Outdated Show resolved Hide resolved
docs/api-guide.md Outdated Show resolved Hide resolved
Co-authored-by: Josh Wong <joshua.wong@scalar-labs.com>
@brfrn169 brfrn169 requested a review from josh-wong November 30, 2023 07:57
@brfrn169
Copy link
Collaborator Author

@josh-wong Thank you for taking at this! I've applied your suggestions. Please take a look again!

Copy link
Member

@josh-wong josh-wong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you!🙇‍♂️

Copy link
Contributor

@feeblefakie feeblefakie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you!

@feeblefakie feeblefakie merged commit f77b0a8 into master Dec 1, 2023
23 checks passed
@feeblefakie feeblefakie deleted the disable-implicit-pre-read-by-default-for-put branch December 1, 2023 01:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants