Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
- We check for transaction support in some parts of Drupal 8 and add locking fallbacks for non-transactional database engines, but we don't do this everywhere that it is needed.
- @catch in #2275535-10: [policy, no patch] Drop support for non-transactional database engines (including MyISAM)
core assumes transaction support anyway - the only way that
supportsTransactions()
returns FALSE is if you explicitly set that as a connection option in settings.php, so we really have no way to support non-transactional engines, but equally no way currently to require transaction support at a code level.
Proposed resolution
- Assume that all drivers are transaction-enabled, and that we will no longer allow to opt-out from transaction-based db operations.
- Deprecate the 'transactions' connection option from settings.php and the
Connection::supportsTransactions()
method. - Remove calls of
Connection::supportsTransactions()
from the codebase, dropping code paths that deal with non-transactional db operations.
Remaining tasks
TBD.
User interface changes
None.
API changes
$databases[$database][$target]['transactions']
settings insettings.php
is deprecated.Connection::supportsTransactions()
is deprecated.
Comment | File | Size | Author |
---|---|---|---|
#38 | interdiff_35-38.txt | 775 bytes | mondrake |
#38 | 2278971-38.patch | 26.64 KB | mondrake |
Comments
Comment #1
Crell CreditAttribution: Crell commentedI am +1 here. Let's simplify the code and eliminate rarely if ever used code paths.
Comment #2
xjmComment #9
mondrakeComment #10
mondrakeAlmost 5 years after, we have an orderly manner to proceed here, i.e. deprecate for removal.
Let's see what a first deprecation patch yields to.
Comment #11
mondrakeWith removals of calls to
::supportsTransactions()
. Mainly leftovers in tests.Comment #13
mondrakeOops
Comment #15
mondrakeComment #17
mondrakeComment #18
mondrakeUpdated IS with what current patch proposes.
Comment #19
mondrakeComment #20
longwaveThis looks like it can just become an assertNotEquals()?
Same here
Comment #21
daffie CreditAttribution: daffie commentedNeeds link to change record.
Are we also deprecation this?
Somewhere in core is a record added to the watchdog table if transactions are not supported. Should that code also be removed?
Comment #22
mondrakeThanks for reviews!
#20 actually that entire test class deserves some phpunit love. Done here.
#21:
1. Sure, but 9.1.0 is a bit away, so we can come back on that when closer.
2. No, but that is no longer dependent on the 'transactions' setting of the connection options, rather inherent to the db, so just moved that to an override of the variable. The abstract implementation is set to FALSE, so no purpose to override in MySQL, wheras for PgSQL and SQLite we set straight to TRUE.
3. I cannot find where that code is.
Comment #23
mondrakeAdding a related issue which is kinda orthogonal to this - I believe that one should be won't fix'ed but ATM still open for any comment.
Comment #24
longwaveRe: #21.3 it looks like this was removed from core in 2010! Maybe @Berdir remembers deleting this code almost 10 years ago in #711108-42: Richer exception reporting for watchdog()? ;)
https://git.drupalcode.org/project/drupal/commit/72db95c988c57d9ac1b073e...
Comment #25
mondrakeComment #26
mondrakeComment #27
mondrakeRerolled. Next, adding reference to a CR in the deprecation errors. There's not a clear CR for dropping support of non-transactional DBs, but there is a clear issue: #2275535: [policy, no patch] Drop support for non-transactional database engines (including MyISAM), that has https://www.drupal.org/node/2278745 as a CR, so will reference the latter.
Comment #28
mondrakeAdded link to CR, both in the issue and the patch.
Comment #30
mondrakeFixes to deprecation message and CS.
Comment #31
daffie CreditAttribution: daffie commentedAll the calls to the method
supportsTransactions()
have been removed.Deprecation triggers have been added.
There is testing for he deprecation triggers.
All my reviewing points have been addressed.
The testbot is happy.
All code changes look good.
The change record is in order.
For me it is RTBC.
I have got the ok from @alexpott to deprecate hook_query_alter, not hook_query_TAG_alter. I have not made an issue for it. If somebody is interested, then go for it. Add an link and I will review your patch.
Comment #32
mondrakeThanks @daffie
I learned https://stackoverflow.com/questions/14561908/phpunit-doesnt-continue-tes... that the test code after the exception will not be executed, so this needs to be reworked.
Comment #33
mondrakeComment #35
mondrakeGood, the test refactoring was wrong. This should be better now.
Comment #36
daffie CreditAttribution: daffie commentedDo you have the same problem here? That the test code stops after the exception will not be run?
Comment #37
mondrakeFor
@expectedDeprecation
? No, that can be accumulated.AFAICU in PHPUnit, when you call
$this->expectException
, then the runner will catch the thrown exception, assert it is thrown, then re-throw it into the test. If the test does not catch the re-throw, it just stops. But deprecation assertions work with listeners instead, it's a different pattern.Comment #38
mondrakeSo, TIL it's the other way round, apparently - you need to catch the exception in the test, assert what you need in the catch block, then re-throw the exception for
$this->expectException
to deal with it.Comment #40
mondrakeComment #41
daffie CreditAttribution: daffie commentedThe changes to the test Drupal\KernelTests\Core\Database\InvalidDataTest look good.
My question on the testing of multiple deprecation message in a single test are answered.
The patch was for me already RTBC.
Back to RTBC.
Comment #43
catchCommitted a1d4b16 and pushed to 9.1.x. Thanks!
#2347867: Race conditions with lock/cache using non-database storage - add a non-transactional database connection was discussion a non-transactional database connection, but it mostly just needs a separate one from the main one, so I think this is good.