Plugin Version: Nascraft v1.9.2
Server Version: Purpur 1.21.10
Environment: Minecraft Server
Description
When running Nascraft v1.9.2 on my Purpur server, the plugin frequently triggers a SQLITE_BUSY error, which causes the server's Watchdog thread to detect a deadlock and force the server to shut down. The error occurs when the plugin attempts to save data to the SQLite database via the saveDayPrice method.
Error Log Snippet
plaintext
java.lang.RuntimeException: org.sqlite.SQLiteException: [SQLITE_BUSY] The database file is locked (database is locked)
at [回收]Nascraft-1.9.2.jar/me.bounser.nascraft.database.commands.ItemProperties.saveItem(ItemProperties.java:51)
at [回收]Nascraft-1.9.2.jar/me.bounser.nascraft.database.sqlite.SQLite.saveEverything(SQLite.java:235)
at [回收]Nascraft-1.9.2.jar/me.bounser.nascraft.database.sqlite.SQLite.disconnect(SQLite.java:79)
at [回收]Nascraft-1.9.2.jar/me.bounser.nascraft.Nascraft.onDisable(Nascraft.java:204)
Caused by: org.sqlite.SQLiteException: [SQLITE_BUSY] The database file is locked (database is locked)
at org.sqlite.core.DB.newSQLException(DB.java:1179)
at org.sqlite.core.DB.execute(DB.java:985)
at org.sqlite.core.DB.executeUpdate(DB.java:1054)
at [回收]Nascraft-1.9.2.jar/me.bounser.nascraft.database.commands.ItemProperties.saveItem(ItemProperties.java:35)
Steps to Reproduce
Start a Purpur 1.21.10 server with Nascraft v1.9.2 installed.
Run the server for a period of time (usually 30+ minutes) with players online.
The server will suddenly crash with the above SQLITE_BUSY error in the logs.
Root Cause Analysis
SQLite is a file-based database that does not support high-concurrency write operations. The Nascraft plugin appears to perform multiple concurrent database write operations (e.g., saveDayPrice, saveItem) without synchronization or retry mechanisms, leading to database file locks.
Expected Behavior
The plugin should handle SQLite concurrency issues properly to avoid database locks.
The server should not crash due to database write conflicts.
Suggested Fixes
Add Synchronization Locks: Implement a global lock object to ensure that only one thread can access the SQLite database at a time (e.g., using synchronized blocks in Java).
Add Retry Mechanism: When a SQLITE_BUSY error occurs, retry the database operation after a short delay (e.g., 100ms) for a limited number of times (e.g., 3 retries).
Increase SQLite Busy Timeout: Set a longer busy timeout for SQLite connections (e.g., 5000ms) to allow the plugin to wait for the database to be released instead of throwing an error immediately.
Support MySQL/MariaDB: Add support for client-server databases (e.g., MySQL) as an alternative to SQLite for servers with high concurrency requirements.
Additional Context
This issue occurs consistently under normal server load with players using Nascraft's features.
Other plugins that use SQLite do not cause similar issues, indicating that the problem is specific to Nascraft's database handling logic.
Plugin Version: Nascraft v1.9.2
Server Version: Purpur 1.21.10
Environment: Minecraft Server
Description
When running Nascraft v1.9.2 on my Purpur server, the plugin frequently triggers a SQLITE_BUSY error, which causes the server's Watchdog thread to detect a deadlock and force the server to shut down. The error occurs when the plugin attempts to save data to the SQLite database via the saveDayPrice method.
Error Log Snippet
plaintext
java.lang.RuntimeException: org.sqlite.SQLiteException: [SQLITE_BUSY] The database file is locked (database is locked)
at [回收]Nascraft-1.9.2.jar/me.bounser.nascraft.database.commands.ItemProperties.saveItem(ItemProperties.java:51)
at [回收]Nascraft-1.9.2.jar/me.bounser.nascraft.database.sqlite.SQLite.saveEverything(SQLite.java:235)
at [回收]Nascraft-1.9.2.jar/me.bounser.nascraft.database.sqlite.SQLite.disconnect(SQLite.java:79)
at [回收]Nascraft-1.9.2.jar/me.bounser.nascraft.Nascraft.onDisable(Nascraft.java:204)
Caused by: org.sqlite.SQLiteException: [SQLITE_BUSY] The database file is locked (database is locked)
at org.sqlite.core.DB.newSQLException(DB.java:1179)
at org.sqlite.core.DB.execute(DB.java:985)
at org.sqlite.core.DB.executeUpdate(DB.java:1054)
at [回收]Nascraft-1.9.2.jar/me.bounser.nascraft.database.commands.ItemProperties.saveItem(ItemProperties.java:35)
Steps to Reproduce
Start a Purpur 1.21.10 server with Nascraft v1.9.2 installed.
Run the server for a period of time (usually 30+ minutes) with players online.
The server will suddenly crash with the above SQLITE_BUSY error in the logs.
Root Cause Analysis
SQLite is a file-based database that does not support high-concurrency write operations. The Nascraft plugin appears to perform multiple concurrent database write operations (e.g., saveDayPrice, saveItem) without synchronization or retry mechanisms, leading to database file locks.
Expected Behavior
The plugin should handle SQLite concurrency issues properly to avoid database locks.
The server should not crash due to database write conflicts.
Suggested Fixes
Add Synchronization Locks: Implement a global lock object to ensure that only one thread can access the SQLite database at a time (e.g., using synchronized blocks in Java).
Add Retry Mechanism: When a SQLITE_BUSY error occurs, retry the database operation after a short delay (e.g., 100ms) for a limited number of times (e.g., 3 retries).
Increase SQLite Busy Timeout: Set a longer busy timeout for SQLite connections (e.g., 5000ms) to allow the plugin to wait for the database to be released instead of throwing an error immediately.
Support MySQL/MariaDB: Add support for client-server databases (e.g., MySQL) as an alternative to SQLite for servers with high concurrency requirements.
Additional Context
This issue occurs consistently under normal server load with players using Nascraft's features.
Other plugins that use SQLite do not cause similar issues, indicating that the problem is specific to Nascraft's database handling logic.