langgenius / langgenius/dify

[Bug]: savepoint error when using oceanbase as database

Open
#38,312 7 comments 3 reactions 0 assignees View on GitHub
🐞 bug 1.15.0 project#dify
Dominant language
TypeScript
Stars
156k
Forks
24.6k
Avg merge
22h 9m
Merged PRs (30d)
610

Description

### Self Checks

- [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
- [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general).
- [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
- [x] I confirm that I am using English to submit this report, otherwise it will be closed.
- [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
- [x] Please do not modify this template :) and fill in all the required fields.

### Dify version

1.15.0

### Cloud or Self Hosted

Self Hosted (Docker)

### Steps to reproduce

After deploying Dify with OceanBase as the backend database, inviting a new user consistently triggers a SAVEPOINT error in the application logs.

### ✔️ Expected Behavior

Dify should successfully invite a new user when using OceanBase as the backend database, without generating any SAVEPOINT-related errors.

### ❌ Actual Behavior

Register failed

```
Traceback (most recent call last):
File "sqlalchemy/engine/base.py", line 1967, in _exec_single_context
self.dialect.do_execute(
File "sqlalchemy/engine/default.py", line 952, in do_execute
cursor.execute(statement, parameters)
File "pymysql/cursors.py", line 153, in execute
result = self._query(query)
File "pymysql/cursors.py", line 322, in _query
conn.query(q)
File "pymysql/connections.py", line 575, in query
self._affected_rows = self._read_query_result(unbuffered=unbuffered)
File "pymysql/connections.py", line 826, in _read_query_result
result.read()
File "pymysql/connections.py", line 1203, in read
first_packet = self.connection._read_packet()
File "pymysql/connections.py", line 782, in _read_packet
packet.raise_for_error()
File "pymysql/protocol.py", line 219, in raise_for_error
err.raise_mysql_exception(self._data)
File "pymysql/err.py", line 150, in raise_mysql_exception
raise errorclass(errno, errval)
OperationalError: (1305, 'savepoint does not exist')

Traceback (most recent call last):
File "services/account_service.py", line 1948, in register
account = AccountService.create_account(
File "services/account_service.py", line 475, in create_account
session.commit()
File "sqlalchemy/orm/scoping.py", line 597, in commit
return self._proxied.commit()
File "sqlalchemy/orm/session.py", line 2030, in commit
trans.commit(_to_root=True)
File "", line 2, in commit
File "sqlalchemy/orm/state_changes.py", line 137, in _go
ret_value = fn(self, *arg, **kw)
File "sqlalchemy/orm/session.py", line 1318, in commit
trans.commit()
File "sqlalchemy/engine/base.py", line 2640, in commit
self._do_commit()
File "sqlalchemy/engine/base.py", line 2865, in _do_commit
self.connection._release_savepoint_impl(self._savepoint)
File "sqlalchemy/engine/base.py", line 1170, in _release_savepoint_impl
self.engine.dialect.do_release_savepoint(self, name)
File "sqlalchemy/engine/default.py", line 774, in do_release_savepoint
connection.execute(expression.ReleaseSavepointClause(name))
File "sqlalchemy/engine/base.py", line 1419, in execute
return meth(
File "sqlalchemy/sql/elements.py", line 527, in _execute_on_connection
return connection._execute_clauseelement(
File "sqlalchemy/engine/base.py", line 1641, in _execute_clauseelement
ret = self._execute_context(
File "sqlalchemy/engine/base.py", line 1846, in _execute_context
return self._exec_single_context(
File "sqlalchemy/engine/base.py", line 1986, in _exec_single_context
self._handle_dbapi_exception(
File "sqlalchemy/engine/base.py", line 2363, in _handle_dbapi_exception
raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
File "sqlalchemy/engine/base.py", line 1967, in _exec_single_context
self.dialect.do_execute(
File "sqlalchemy/engine/default.py", line 952, in do_execute
cursor.execute(statement, parameters)
File "pymysql/cursors.py", line 153, in execute
result = self._query(query)
File "pymysql/cursors.py", line 322, in _query
conn.query(q)
File "pymysql/connections.py", line 575, in query
self._affected_rows = self._read_query_result(unbuffered=unbuffered)
File "pymysql/connections.py", line 826, in _read_query_result
result.read()
File "pymysql/connections.py", line 1203, in read
first_packet = self.connection._read_packet()
File "pymysql/connections.py", line 782, in _read_packet
packet.raise_for_error()
File "pymysql/protocol.py", line 219, in raise_for_error
err.raise_mysql_exception(self._data)
File "pymysql/err.py", line 150, in raise_mysql_exception
raise errorclass(errno, errval)
OperationalError: (pymysql.err.OperationalError) (1305, 'savepoint does not exist')
[SQL: RELEASE SAVEPOINT sa_savepoint_1]
(Background on this error at: https://sqlalche.me/e/20/e3q8)
```

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the user-registration failure with Dify 1.15.0 deployed using OceanBase, then trace the transaction and savepoint handling around `services/account_service.py`, especially `create_account` and `register`. The report includes a SQLAlchemy traceback ending in `RELEASE SAVEPOINT sa_savepoint_1`; use it to investigate where the savepoint is lost. Done means inviting a user with OceanBase succeeds without the SAVEPOINT error.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, mysql, postgresql, python, sqlalchemy
Domain
backend, database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.