adamsaghy commented on PR #6494:
URL: https://github.com/apache/fineract/pull/6494#issuecomment-6591802277

   > Thank you @galovics . @adamsaghy please let me know your thoughts on this 
as well.
   
   Thanks @galovics, good catch. I looked into it and agree on the direction, 
but @Transactional(readOnly = true) alone won’t close this:
   
   The annotation has no effect on the primary transaction manager. The 
@Primary one is ExtendedJpaTransactionManager. With EclipseLink, Spring doesn’t 
set read-only on the JDBC connection, so readOnly = true only changes the flush 
mode. We’d need to run the report through jdbcTransactionManager and send SET 
TRANSACTION READ ONLY ourselves as the first statement. 
ExtendedDataSourceTransactionManager only turns on enforceReadOnly when the 
instance is in read-only mode. Sending the statement ourselves also settles 
your MariaDB question, since we wouldn’t depend on the driver passing 
setReadOnly on. MariaDB, MySQL and PostgreSQL all accept it at the start of a 
transaction.
   On PostgreSQL, a read-only transaction can be escaped with several 
statements. pgjdbc splits on ;, so SELECT 1; COMMIT; DELETE FROM m_loan ends 
the read-only transaction and runs the DELETE in a normal one. 
set_config('default_transaction_read_only', 'off', ...) works the same way. So 
we also need a single-statement check. That doesn’t mean writing our own lexer: 
org.postgresql.core.Parser.parseJdbcSql(...) returns one NativeQuery per 
statement with its command type. Requiring exactly one SELECT/WITH statement 
uses the same splitting the driver applies. MariaDB and MySQL don’t need this, 
because allowMultiQueries is off by default and MariaDB has no data-modifying 
CTEs.
   
   Also, the wrapper never fully protected PostgreSQL. Report SQL like SELECT 
1) x; DELETE FROM m_loan; SELECT * FROM (SELECT 1 becomes three valid 
statements once wrapped. This PR doesn’t open a new hole; the gap is already on 
develop.
   
   So I’d merge this as is and handle it in a follow-up ticket:
   
   run report SQL in a JDBC read-only transaction with an explicit SET 
TRANSACTION READ ONLY
   on PostgreSQL, reject report SQL that pgjdbc’s parser splits into more than 
one statement
   tests: COMMIT; chaining and a DML CTE on PostgreSQL, and a function that 
writes, called from a SELECT, on MariaDB
   longer term: let report execution use a connection whose database user only 
has SELECT grants (the tenant’s readonly_schema_* settings could be reused), 
which nothing in the SQL can get around
   
   @AshharAhmadKhan, would you like to take the follow-up?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to