-
-
Notifications
You must be signed in to change notification settings - Fork 191
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
feat: Support lock-and-fetch for MSSQL. Explicit LIMIT for all. #371
Conversation
Remaining to test against MSSQL. Verified to work with postgres using new generic method that is transaction-based. |
This is a bit tricky to test since Testcontainers does not seem to work on M1 Macs and testing via Github Actions sporadically fails. I have done some local testing using AzureSQLEdge, and the lock-and-fetch strategy seem to be working. If anyone using MSSQL could try this branch out that would be helpful. With a little luck this might fix the deadlock issues experienced using the default polling strategy. I have gotten the deadlock locally (AzureSQLEdge) using default polling, but not using lock-and-fetch. Is it possible for you do help out verifying this change for MSSQL @rafaelhofmann ? This is the query currently in use: @Override
public String createGenericSelectForUpdateQuery(String tableName, int limit, String requiredAndCondition) {
return "select TOP "+limit+" * from " + tableName +
" WITH (readpast,rowlock) where picked = ? and execution_time <= ? " + requiredAndCondition +
" order by execution_time asc ";
} |
I added |
Hi @kagkarlsson I will test this new branch and check if we still have problems with the indexes. |
I have enabled both polling-strategies for MSSQL in this branch. Both seem to run successfully on GA via Additionally, I added hints to skip locked to default-query as well since deadlocks were causing sporadic test-failures (for MSSQL) |
Hi @kagkarlsson, Do you have a published snapshot version that we can use to test or should we build our own version? Thanks |
Currently you would need to build your own. Let me know if that is a problem. |
I have built the branch and upgraded our ACPT system (including all the indexes that were deleted in the past) to the new release, but we are running into the same problem as before: A deadlock about once every hour, when we have a load of 300 tasks/min. String selectForUpdateQuery =
" UPDATE " + ctx.tableName +
" SET " + ctx.tableName + ".picked = ?, " +
" " + ctx.tableName + ".picked_by = ?, " +
" " + ctx.tableName + ".last_heartbeat = ?, " +
" " + ctx.tableName + ".version = " + ctx.tableName + ".version + 1 " +
" OUTPUT [inserted].* " +
" FROM ( " +
" SELECT TOP(?) ist2.task_name, ist2.task_instance " +
" FROM " + ctx.tableName + " ist2 WITH (ROWLOCK, READPAST) " +
" WHERE ist2.picked = ? AND ist2.execution_time <= ? " + unresolvedFilter.andCondition() +
" ORDER BY ist2.execution_time ASC " +
" ) AS st2 " +
" WHERE st2.task_name = " + ctx.tableName + ".task_name " +
" AND st2.task_instance = " + ctx.tableName + ".task_instance"; In theory this should do the same as the |
Ok, thanks. Did you try both |
Your combined query looks interesting |
We had deadlocks with the |
How has the |
…. Tentative support for detecting MariaDB and MaraiDB compatibility-test.
Great fix! Any ETA on release with this fix? |
Good question, nothing blocking it from being released, just time I guess :). Hopefully I can release it within 1-2 weeks |
🎉 This issue has been resolved in |
Hi! I am currently evaluating db-scheduler for our use-cases and doing some code reviews in the process. I see that the I don't particularly care about older versions of MariaDB, but I just want to let you know that the versions 10.4 and 10.5 are technically still supported, according to https://mariadb.com/kb/en/mariadb-server-release-dates/. I see you already differentiate the versions of MySQL, so maybe you want to do the same for MariaDB. Anyway, thank you for your work! I like the simplicity of db-scheduler and I hope we can use it to eventually replace Quartz, which seems to be completely dead by now. |
I had some issue when testing the support in MySQL (or MariaDB) and limited time, so I opted for disabling the support until someone had the time to verify it works as expected. Feel free to fork and try it out. @Override
public boolean supportsGenericLockAndFetch() {
// FIXLATER: fix syntax and enable it for versions of MariaDB that supports it
return false;
} |
The support was nearly finished in kagkarlsson#371 but later commented out due to "some issue [..] and limited time". I tried to find out what those issues were and discovered that the syntax of the select was wrong. In MySQL the `LIMIT` comes before the `FOR UPDATE SKIP LOCKED`. Using that fix `Mysql8CompatibilityTest` passes, I have done no further testing yet.
JdbcCustomizations
. (Groundwork necessary to supportSELECT FOR UPDATE .. SKIP LOCKED
and explicitLIMIT
for different databases.)JdbcCustomization
lock-and-fetch
aka.SELECT FOR UPDATE .. SKIP LOCKED
for MSSQL/SqlServer. However, testing has shown that lock-and-fetch is prone to deadlocks for SqlServer, so it is not recommended until that is understood/resolved (reproduce via disabled test inMssqlClusterTest
). A silver-lining is that a query-hint was also added tofetch-and-lock-on-execute
for SqlServer, and it appears this resolves issues with deadlocks for that (default) strategy.micro-jdbc
JdbcRunner
and refactor transaction-handling (see PR #4)micro-jdbc
dependencyFixes
Further work / fix later
Reminders
cc @kagkarlsson