Skip to content

DefaultLockRepository fails silently w/ PostgreSQL #8623

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

Closed
agebhar1 opened this issue May 16, 2023 · 4 comments
Closed

DefaultLockRepository fails silently w/ PostgreSQL #8623

agebhar1 opened this issue May 16, 2023 · 4 comments

Comments

@agebhar1
Copy link
Contributor

In what version(s) of Spring Integration are you seeing this issue?

unreleased main

Describe the bug

In #8606 ttl type moved to Duration and is used with JdbcTemplate, e.g.

public boolean acquire(String lock) {
Boolean result =
this.serializableTransactionTemplate.execute(
transactionStatus -> {
if (this.template.update(this.updateQuery, this.id, Instant.now(),
this.region, lock, this.id, Instant.now().minus(this.ttl)) > 0) {
return true;
}
try {
return this.template.update(this.insertQuery, this.region, lock, this.id,
Instant.now()) > 0;
}
catch (DataIntegrityViolationException ex) {
return false;
}
});
return Boolean.TRUE.equals(result);
}

Acquire fails silently with PostgreSQL and propagated back to:

public void lock() {
this.delegate.lock();
while (true) {
try {
while (!doLock()) {
Thread.sleep(this.idleBetweenTries.toMillis());
}
break;
}
catch (TransientDataAccessException | TransactionTimedOutException | TransactionSystemException e) {
// try again
}
catch (InterruptedException e) {
/*
* This method must be uninterruptible so catch and ignore
* interrupts and only break out of the while loop when
* we get the lock.
*/
}
catch (Exception e) {
this.delegate.unlock();
rethrowAsLockException(e);
}
}
}

and handled in the last clause:

catch (Exception e) {
  this.delegate.unlock();
  rethrowAsLockException(e);
}

with this exception:

org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [UPDATE LOCK
SET CLIENT_ID=?, CREATED_DATE=?
WHERE REGION=? AND LOCK_KEY=? AND (CLIENT_ID=? OR CREATED_DATE<?)
]; nested exception is org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of java.time.Instant. Use setObject() with an explicit Types value to specify the type to use.

Expected behavior

Should acquire the lock with PostgreSQL.

@agebhar1 agebhar1 added status: waiting-for-triage The issue need to be evaluated and its future decided type: bug labels May 16, 2023
@artembilan
Copy link
Member

Can't infer the SQL type to use for an instance of java.time.Instant

OK. Sounds like there is no automatic conversion from that type to temporal one on driver level.
Will fix it shortly using toEpochMilli()...

@artembilan artembilan added this to the 6.1.0 milestone May 16, 2023
@artembilan artembilan added in: jdbc and removed status: waiting-for-triage The issue need to be evaluated and its future decided labels May 16, 2023
@artembilan
Copy link
Member

Well, That doesn't work because toEpochMilli() is essentially a BIGINT, not a TIMESTAMP.
So, that is not OK.

How about to see if you can move your PostgreSQL server to the latest one?
According to the discussion here: https://stackoverflow.com/questions/25536969/spring-jdbc-postgres-sql-java-8-conversion-from-to-localdate

The fix has been done in the 9.4.1212:

I fixed my org.postgresql.util.PSQLException: Cant infer the SQL type to use for an instance of java.time.LocalDate. Use setObject() with an explicit Types value to specify the type to use exception updating my postgres JDBC from 9.4 Build 1206 to 9.4.1212 version.

BTW, does it work with the current Spring Integration 6.0.5 ?
We do have there a logic like this:

LocalDateTime.now(ZoneOffset.UTC)

Yeah... Probably if that works, and even if Instant works with the latest PostgreSQL, we just bring that LocalDateTime back and that's it.
We just cannot be sure what server is in use and follow Postel's Law as much as possible 🤷

@artembilan
Copy link
Member

Looks like the driver doesn't support java.time.Instant: https://tada.github.io/pljava/use/datetime.html.

Therefore my assumption about bringing LocalDateTime logic should be correct.

@agebhar1
Copy link
Contributor Author

@artembilan 6.0.5 is working fine with the LocalDateTime.now(ZoneOffset.UTC) implementation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants