-
Notifications
You must be signed in to change notification settings - Fork 435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQL Database Error 924 – Database is already open and can only have one user at a time #1071
Comments
Hi @Springrbua, the driver will internally use the same connection the user created when calling these APIs. If your Updater class only establishes 1 connection at a time to the database and no other parts of your program creates simultaneous connections, the driver will use that connection when retrieving DatabaseMetadata. This seems more like an issue with the program logic itself as SINGLE_USER is a database side property, and the user application must properly manage its resources with SINGLE_USER restrictions in mind. The only change I can see regarding these APIs is that they've taken a performance hit in favor of conforming to JDBC Specs, which will not be changed. The APIs before #490 also had similar logic with regards to contacting the server, the only difference is it was faster. I don't believe this is a driver regression. You mentioned the updater is executed in SINGLE_USER mode on purpose to ensure others are not working on the database. A solution here would be to properly handle this error as it's an error thrown from the SQL Server when multiple users are attempting to access the DB while it's in SINGLE_USER mode. You can simply catch the SQLException and verify the error, and continue with some kind of retry logic until the database is no longer in use/SINGLE_USER mode. |
@rene-ye thak you for the quick reply. |
Hi @Springrbua, the DatabaseMetadata APIs mentioned in the thread does not open new connections internally. If possible, can you provide a standalone java project which exhibits this behavior? |
We tryed to implement this workaround. Our current solution is to catch the Exception, wait for 3 seconds and retry the statement. We have to retry it about 5 times on average until the statement works.
The profiler in the SQL Server Management Studio didn't log any new connection, so the second connection does not seem to come from our logic or from the driver. Thats why my guess is, that the SQL Server (not the driver) opens a new connection internally or works asynchronously and therefore reports the error, when executing the next statement.
The project, in which we are facing this issue is pretty big. The database contains about 1000 tables, I don't think that the issue is reproduceable in a small standalone project. Since this problem occures only with driver versions > 6.3.3 and the error reported comes from the |
Hi @Springrbua, I attempted to reproduce the error message mentioned in the thread, but was unable to do so. Attempting to create a new connection to a SINGLE_USER database with an existing connection simply returns a "connection failed..." error. There's not too much we can do from the driver side for now, but the stored procedure changes from #490 will not be reverted as they align the driver with JDBC Specifications. |
First of all, thank you for your effort!
This probably reinforces my presumption, that the second connection comes from the SQL Server (not the driver) itself.
I understand that those changes won't be reverted. I was just hoping for some advice on how to track down the cause of this Issue, since the workaround (wait and retry) seems a bit hacky. I managed to create a "patched" version of the 6.3.3 driver, without the changes of #490 by following this steps:
With this "patched" driver version, I can't reproduce the error, so it must be somehow related to #490. I also noticed, that the issue only occures, when the updater changes the structure of the database (for example by using some I did some research regarding the single user mode and found this article, which contains the folliwng prequisite:
The flag is not turned on in our case, so thats not the issue, but this prequisite clearly states, that if the SQL Server (again, not the driver) does some asynchronous jobs, the database cannot be in single user mode. Since I am not an expert, I would like to hear your opinion on my assumption. |
Hi @Springrbua, feel free to share this issue w/ the SQL Server team. I don't really know enough about the underlying operations SQL Server is performing to comment on whether the assumptions here are correct. I can only confirm that the driver is not opening new connections against the database when these APIs are called. |
@rene-ye thak you again for your help, I'll report it to the SQL Server team and update this thread, if I get some feedback. |
Hi @Springrbua, I believe the public forum for SQL Server is: https://feedback.azure.com/forums/908035-sql-server |
@rene-ye I openend a thread on the public forum. |
Hi @Springrbua, |
@rene-ye @ulvii I posted this problem on the msdn forums and one of the users was able to create a minimal reproduction of the problem.
He also listed some possible solutions:
So it would be cool if you could take another look at it, since our workaround (wait and retry) does not seem to solve the problem, but just reduces it's frequency. |
Hi @Springrbua, Based on the logs, looks like you are setting I would also suggest to update the thread with the reproduction steps. |
@ulvii thank you for the information, I just tried it again using
The reproduction does actually come from that thread, the user Erland Sommarskog was able to reproduce the bug:
|
My apologies, I meant to update your initial thread. We were forced to use temporary tables to join |
Driver version
Since 6.3.3 Preview Release (also testet with 7.3.0 Preview Release)
Worked well with 6.3.2 Preview Release and earlier.
SQL Server version
Microsoft SQL Server 2017 (RTM-CU14-GDR) (KB4494352) - 14.0.3103.1 (X64) Mar 22 2019 22:33:11 Copyright (C) 2017 Microsoft Corporation Developer Edition (64-bit) on Windows 10 Pro 10.0 (Build 17763: )
also tested with Microsoft SQL Server 2014
Client Operating System
Windows 10
JAVA/JVM version
1.8.0 and also tested with java 11 (open jdk)
Problem description
In an application I am working on, I have an updater, which updates the db structure whenever a new version is started for the first time.
This updater is executed in single user mode, to ensure no one is working on the db in the meantime.
During this update, I request meta data using
SQLServerDatabaseMetaData#getImportedKeys
andSQLServerDatabaseMetaData#getExportedKeys
.This call sometimes causes a
com.microsoft.sqlserver.jdbc.SQLServerException
with the messageDatabase is already open and can only have one user at a time
(SQLServer Errorcode 924).Stacktrace:
This exception only seems to occur when the database is on a slow drive (HDD). The same database works fine, when I test it on my SSD.
I did some research and I guess the error was introduced with #490.
JDBC trace logs
https://gist.github.com/Springrbua/8760cf873cc337c189fc2e1d47f7682b#file-log-txt
The text was updated successfully, but these errors were encountered: