Overview
Singleton, is a one of most popular design pattern. The main purpose is to saving memory by reuse and sharing one instance rather than create a new one. It sounds like a great concept, but it could be a "Boomerang" if we implement that concept in the wrong case.
Helo, i am Satria. Currently i'm working on Tech Company as a Software Engineer. In this article i will share about my experience in implementing Singleton Design Pattern in the wrong case. So, let's go.
Problem Started
The Incident is started when i created an application to manage the budgeting system in our company. It is using PostgreSQL as a Database Management System. The application that i built is a part of Company's Super App.
When I looked at the code in the Super App, i notice that everytime when we need to query to database, we always use the same database connection and database session that declared as a global variable. here's the sample code
embed engine = create_engine(url)
Session = sessionmaker(bind=engine)
db = Session()
Everytime we need to querying to database, we always use db variable. For the first time, i thought
Hmm, This is good. we can reduce the memory usage
Everything going well when i test and debug the application by myself. But the problem occuring when i entering the UAT Process. A lot of issues coming from users in day 1,and 60% of issues is about Inconsistency Data. on the next day the same issue is still coming. and Users put the comment like this
Why my proposal data is not found?, Why my proposal data is different than i created before, why the approval process is stuck?
Resolving The Problem
At First i thought that the problem is coming from relationship between the table. So, i double-checked on the model and database schema. But, i found no problem with that. i also check the query to database, and still didn't find the problem, the query is fine.
I tried all flow of the application again, and still didn't find t the problem. I’m really stressed out by this issue, I spent 3 days just trying to find the problem. On day 3, i remember that my application is using same database session for all query. And when i check on entry point file, our app is using 4 worker and every worker can running up to 50 threads. That's caused the race condition because one database session is used by more than one Thread. So, i tried to refactor my code and create new database session in every function.
def create_proposal():
db_session = Session()
try{
....
except:
db_session.rollback()
finally:
db_session.close()
After i refactoring the code like above, The related issue is gone. And my application is ready to serve on Production.
Conclusion
Singleton is a good concept to reduce memory usage. but not all type of instances is good to use singleton. In this case, database connection is suitable to use Singleton, because the data doesn't change everytime it's used. But implementing a Singleton for a database session is a bad practice, because a database session can change every time it is used.
Top comments (0)