mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 09:37:45 +00:00
fix(handler): optimise snapshot hanlding (#8652)
# Which Problems Are Solved
There are cases where not all statements of multiExec are succeed. This
leads to inconsistent states. One example is [LDAP
IDPs](https://github.com/zitadel/zitadel/issues/7959).
If statements get executed only partially this can lead to inconsistent
states or even break projections for objects which might not were
correctly created in a sub table.
This behaviour is possible because we use
[`SAVEPOINTS`](https://www.postgresql.org/docs/current/sql-savepoint.html)
during each statement of a multiExec.
# How the Problems Are Solved
SAVEPOINTS are only created at the beginning of an exec function not
during every execution like before. Additionally `RELEASE` or `ROLLBACK`
of `SAVEPOINTS` are only used when needed.
# Additional Changes
- refactor some unused parameters
# Additional Context
- closes https://github.com/zitadel/zitadel/issues/7959
(cherry picked from commit ddeeeed303
)
This commit is contained in:
@@ -264,11 +264,23 @@ func NewViewCheck(selectStmt string, secondaryTables ...*SuffixedTable) *handler
|
||||
}
|
||||
|
||||
func execNextIfExists(config execConfig, q query, opts []execOption, executeNext bool) func(handler.Executer, string) (bool, error) {
|
||||
return func(handler handler.Executer, name string) (bool, error) {
|
||||
err := exec(config, q, opts)(handler, name)
|
||||
if isErrAlreadyExists(err) {
|
||||
return executeNext, nil
|
||||
return func(handler handler.Executer, name string) (shouldExecuteNext bool, err error) {
|
||||
_, err = handler.Exec("SAVEPOINT exec_stmt")
|
||||
if err != nil {
|
||||
return false, zerrors.ThrowInternal(err, "V2-U1wlz", "create savepoint failed")
|
||||
}
|
||||
defer func() {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if isErrAlreadyExists(err) {
|
||||
_, err = handler.Exec("ROLLBACK TO SAVEPOINT exec_stmt")
|
||||
shouldExecuteNext = executeNext
|
||||
return
|
||||
}
|
||||
}()
|
||||
err = exec(config, q, opts)(handler, name)
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user