Repository navigation
Feature: Add transaction isolation level and mode settings to pdo_firebird - #12815
Conversation
There was a problem hiding this comment.
Should I make it an error?
There was a problem hiding this comment.
I took a closer look, and the ret value is a mess. I don't know what it want to do by returning -1.
I would like to leave this as is for now and fix it all together in a separate pull request.
There was a problem hiding this comment.
Can this case ever happen? The attribute should be controlled by the driver and only return valid values. So I would probably make this an assertion.
There was a problem hiding this comment.
This value is set by users, so any value that is an int will come here. Therefore, it is quite possible that values other than the three constant values will be passed.
factory may need validation and errors as same as set attr.
There was a problem hiding this comment.
I would possibly throw a ValueError as trying to use an invalid transaction isolation mode is a programming error.
There was a problem hiding this comment.
Both the constructor and set attr have been fixed to cause a value error.
b7d932f
However, I am a little confused about whether it would be better to write zend_restore_error_handling in pdo core.
There was a problem hiding this comment.
Ah, zend_value_error is better. I'll fix it.
|
Could you please review it when you have time? |
There was a problem hiding this comment.
| if (!php_firebird_begin_transaction(dbh, /* manually */ false)) { | |
| if (!php_firebird_begin_transaction(dbh, /* auto commit mode */ false)) { |
There was a problem hiding this comment.
Fixed on e1fd726
retain comment was also difficult to understand, so I fixed it as well.
There was a problem hiding this comment.
I'd throw a ValueError instead, as this is a Firebird specific attribute.
There was a problem hiding this comment.
| char tpb[5] = { isc_tpb_version3 }, *ptpb = tpb + 1; | |
| /* tpb means "Transaction Parameter Buffer" */ | |
| char tpb[] = { isc_tpb_version3 }; | |
| char *ptpb = tpb + 1; |
The tpb might not be consistent across versions?
I don't really get how the pointer is being initialized and also why it is updated twice sometimes, as it will overwrite the table?
If this is intended, then using tpb[1] = isc_tpb_read_committed is possibly easier to understand. But comments around the Interbase/Firebird API would be helpful as this is confusing.
There was a problem hiding this comment.
If it is not an API with the FB_ prefix, it seems safe to assume that there is no difference between versions. Therefore, there are no differences between versions in the tpb specifications.
I think I can write it a little more clearly, so I'll try rewriting it.
There was a problem hiding this comment.
I tried to rewrite it a little easier to understand.
efa0d98
The setting add more 1 byte for read committed, because firebird's read committed supports multiple modes of behavior.
isc_tpb_rec_version is the mode for reading from committed data.
The opposite setting is isc_tpb_no_rec_version. This is a mode in which uncommitted data waits for it to be committed (or rolled back) and then read.
Detailed documentation on these:
https://docwiki.embarcadero.com/InterBase/2020/en/Specifying_Isolation_Level
There was a problem hiding this comment.
FYI, when reading some times within a transaction, the phenomenon where different data is read due to updates by other transactions is called "Phantom Read".
(I deleted the comment about Phantom Read because it might have been difficult to understand.)
There was a problem hiding this comment.
@Girgias
Using strlen on char arrays doesn't seem to work well on windows. (It may be wrong to use strlen for arrays in the first place.)
I rewrote it for now and the test passed, but which one seems better, the one using the pointer?
There was a problem hiding this comment.
Can this case ever happen? The attribute should be controlled by the driver and only return valid values. So I would probably make this an assertion.
|
I made a mistake. It's late today, so I'll fix it tomorrow. |
cdca462 to
ac8516a
Compare
|
Passed! |
b887eea to
55c7be2
Compare
There was a problem hiding this comment.
| /* Not wait to commit indeterminate data. This option required only with `read committed`.*/ | |
| /* Do not wait to commit indeterminate data. This option only required with `read committed`. */ |
Not sure what you mean by "indeterminate" ?
There was a problem hiding this comment.
I don't know why the sentence is like this....Maybe I was tired.
It should have been a comment like this, I'll fix it.
Ignore indeterminate data from other transactions.
Indeterminate data from other transactions means data that has not been committed or rolled back in other transactions.
There was a problem hiding this comment.
I would possibly throw a ValueError as trying to use an invalid transaction isolation mode is a programming error.
a70544b to
2cebb13
Compare
2cebb13 to
b3caa01
Compare
…B_TRANSACTION_ISOLATION_LEVEL.
b7d932f to
04235aa
Compare
Girgias
left a comment
There was a problem hiding this comment.
Makes sense to me, can you add an entry to UPGRADING/NEWS? :)
| zend_value_error("PDO::FB_TRANSACTION_ISOLATION_LEVEL must be a valid transaction isolation level " | ||
| "(PDO::FB_READ_COMMITTED, PDO::FB_REPEATABLE_READ, or PDO::FB_SERIALIZABLE)"); |
There was a problem hiding this comment.
This is just a possible follow-up suggestion to extract the common error message into a function so that they don't go out of sync.
|
Thanks! |
take2 of #12664
About Firebird transaction isolation levels
Firebird's transaction isolation level can only be set at the beginning of a transaction. Therefore, I saved the user's settings on the php side and used them when starting a transaction.
Default is
repeatable lead.Firebird's
read committedhas three types of behaviorFor this pull request, I adopted 1, which is a common
read committed.It is possible to switch between 2 and 3 by attribute value, but I have decided that there is no need to implement it yet as I do not know the demand.
About access mode
There are writable and read-only modes. Like isolation levels, this can only be set at the beginning of a transaction. In the same way, the setting value is retained on the php side.
Default is
writable.Auto commit mode
Firebird's autocommit mode is emulated by PHP, which actually always has a transaction open. If a transaction in autocommit mode is run at a high isolation level, it will not be able to read any changes made by other transactions after
new PDO().Therefore, I made the autocommit mode to always work with
read committed, regardless of the user's configured value.