-
-
Notifications
You must be signed in to change notification settings - Fork 264
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
Transaction setReadOnly #3495
Transaction setReadOnly #3495
Conversation
|
This PR looks good. I'm happy with the test and change. |
yes, some databases execute the COMMIT successful. I modified the test like this and tried it locally with a few database platforms: @Test
public void testReadOnlyTransactionWithUpdateQuery() {
ResetBasicData.reset();
try (Transaction txn = DB.beginTransaction()) {
txn.setReadOnly(true);
DB.update(Customer.class).set("name", "Rob2").where().eq("name", "Rob").update();
txn.commit();
}
assertThat(DB.find(Customer.class).where().eq("name", "Rob2").exists()).isTrue();
} h2, db2, mariadb and sqlserver19 execute the update query despite Exception flies in mysql: and for postgres: (I haven't tested the other platforms) |
@rbygrave I wrote a few more tests and added fixes in other places. Can you please review again and give me feedback? |
Thanks. I made a change where I moved the markNotQueryOnly() into the initTransIfRequired(); and initTransIfRequiredWithBatchCascade() methods. I felt that this was just slightly a better in case any future use of those methods gets added. I couldn't push that change to this branch so I've merged this into master now with that small adjustment. Great work, thanks !! |
I was expecting db2, mariadb and sqlserver to do better there - rather surprising. Thanks for adding those details. |
Hello @rbygrave ,
we have the following use case: in some cases we would like to allow the user to start a so-called test run, e.g. updating the user data using external LDAP. The test run does not perform any writing operations in the database, but returns a CSV file of what the updated data would look like. The user can then look at this CSV to see whether the update would be correct and whether they still need to tweak a few parameters of the LDAP import.
The use case runs in a transaction that could potentially be quite large. For this reason, we don't want to rely on a transaction rollback operation. We don't want to put unnecessary load on the database (our experience shows that this is particularly bad with too big DB2 transaction logs).
We tried
transaction.setReadOnly(true)
which did not reflect our expected results. We thought that if the transaction is in read-only mode and a write operation is called (update/delete), an exception will be thrown and the further process will be aborted.I have developed a unit test and a possible solution proposal for this. Can you please take a look if it would go in the right direction?
We have chosen a central location that is called for updates/deletes:
markNotQueryOnly
. Here I queried the local variable because most connections (e.g. H2) don't notice this andconnection.isReadOnly
returns the wrong result.Of course, as I receive feedback, I can create more tests and consider other implementations of the
markNotQueryOnly
.What else we tried: we create the transaction with readonly scope as
try (Transaction txn = DB.beginTransaction(TxScope.required().setReadOnly(true))) { ...
. It works for a single tenant mode (such as the unittests) but it does not work in a multi tenant mode.Cheers,
Noemi