Skip to content

Commit

Permalink
[BUGFIX] Install tool database row updater works with mssql
Browse files Browse the repository at this point in the history
SqlServer can not handle a transaction for a table, if the
same table is queried currently. The install tool database
row updater does this. Solution is to skip the transaction
on this platform. Additionally, an update query is fixed
to hint for proper field types.

Resolves: #92832
Releases: master, 10.4
Change-Id: I5fc76705088a727dc1ff41410d6e2cd02b3d9655
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/66586
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Benni Mack <benni@typo3.org>
  • Loading branch information
lolli42 authored and bmack committed Nov 13, 2020
1 parent 16501d7 commit 2041300
Showing 1 changed file with 15 additions and 4 deletions.
19 changes: 15 additions & 4 deletions typo3/sysext/install/Classes/Updates/DatabaseRowsUpdateWizard.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace TYPO3\CMS\Install\Updates;

use Doctrine\DBAL\Platforms\SQLServerPlatform;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Registry;
Expand Down Expand Up @@ -220,8 +221,10 @@ public function executeUpdate(): bool
'table' => $table,
'uid' => $rowBefore['uid'],
];
if ($connectionForSysRegistry === $connectionForTable) {
// Target table and sys_registry table are on the same connection, use a transaction
if ($connectionForSysRegistry === $connectionForTable
&& !($connectionForSysRegistry->getDatabasePlatform() instanceof SQLServerPlatform)
) {
// Target table and sys_registry table are on the same connection and not mssql, use a transaction
$connectionForTable->beginTransaction();
try {
$this->updateOrDeleteRow(
Expand All @@ -238,8 +241,10 @@ public function executeUpdate(): bool
throw $up;
}
} else {
// Different connections for table and sys_registry -> execute two
// distinct queries and hope for the best.
// Either different connections for table and sys_registry, or mssql.
// SqlServer can not run a transaction for a table if the same table is queried
// currently - our above ->fetch() main loop.
// So, execute two distinct queries and hope for the best.
$this->updateOrDeleteRow(
$connectionForTable,
$connectionForSysRegistry,
Expand Down Expand Up @@ -343,6 +348,12 @@ protected function updateOrDeleteRow(Connection $connectionForTable, Connection
[
'entry_namespace' => 'installUpdateRows',
'entry_key' => 'rowUpdatePosition',
],
[
// Needs to be declared LOB, so MSSQL can handle the conversion from string (nvarchar) to blob (varbinary)
'entry_value' => \PDO::PARAM_LOB,
'entry_namespace' => \PDO::PARAM_STR,
'entry_key' => \PDO::PARAM_STR,
]
);
}
Expand Down

0 comments on commit 2041300

Please sign in to comment.