I've got a large multi-threaded webapp in which I am passing in jdbcTemplates into DAO classes via constructor injection. Is this a multi-threading risk? Should I be passing in just the datasource instead?
Spring IOC runs in only 1 thread on start up so threading issues are not an issue there. Spring will not publish the DAO as a bean (to be retrieved from elsewhere) until it is completely constructed.
There is no risk of multithreading, you can safely pass jdbcTemplate into DAO classes.
In every query execution method, it essentially talks to the injected datasource and does not use any state which could lead to any side effect.
Related
I read a lot of documents and articles about DBcontext in Efcore and its lifetime, however, I have some questions.
Based on this link "https://learn.microsoft.com/en-us/ef/core/dbcontext-configuration/" the best lifetime of DBcontext and default lifetime of AddDbContext is scope, but there is a contradiction in the two below sentences on this document.
"DbContext is not thread-safe. Do not share contexts between
threads. Make sure to await all async calls before continuing to use
the context instance."
on the other hand, it was mentioned too,
"Dbcontext is safe from concurrent access issues in most
ASP.NET Core applications because there is only one thread executing
each client request at a given time, and because each request gets
a separate dependency injection scope (and therefore a separate
DbContext instance)."
I was confused about whether registering DBcontext as a scoped service is thread-safe or not?
What are the problems of registering DBcontext as a singleton service in detail?
In addition, I read some docs that prohibit registering singleton DbContext, however, AddDbContextPool makes to register singleton DBcontext.
so there are some questions about the Dbcontextpool.
what are the impacts of using the DbContextPool instead of the DbContext?
when we should use it and what should be considered when we use contextPool?
DbContextPool is thread-safe?
Has it memory issues because of storing a number of dbset instances throughout the application's lifetime?
change-tracking or any parts of the ef would be failed or not in the DB context pool?
One DbContext per web request... why?
.NET Entity Framework and transactions
I understand why you think the language in the Microsoft documents is confusing. I'll unravel it for you:
"DbContext is not thread-safe." This statement means that it's not safe to access a DbContext from multiple threads in parallel. The stack overflow answers you already referenced, explain this.
"Do not share contexts between threads." This statement is confusing, because asynchronous (async/await) operations have the tendency to run across multiple threads, although never in parallel. A simpler statement would be: "do not share contexts between web requests," because a single web request typically runs a single unit of work and although it might run its code asynchronously, it typically doesn't run its code in parallel.
"Dbcontext is safe from concurrent access issues in most ASP.NET Core applications": This text is a bit misleading, because it might make the reader believe that DbContext instances are thread-safe, but they aren't. What the writers mean to say here is that, with the default configuration (i.e. using AddDbContext<T>(), ASP.NET Core ensures that each request gets its own DbContext instance, making it, therefore, "safe from concurrent access" by default.
1 I was confused about whether registering DBcontext as a scoped service is thread-safe or not?
DbContext instances are by themselves not thread-safe, which is why you should register them as Scoped, because that would prevent them from being accessed from multiple requests, which would make their use thread-safe.
2 What are the problems of registering DBcontext as a singleton service in detail?
This is already described in detail in this answer, which you already referenced. I think that answer goes into a lot of detail, which I won't repeat here.
In addition, I read some docs that prohibit registering singleton DbContext, however, AddDbContextPool makes to register singleton DBcontext. so there are some questions about the Dbcontextpool.
The DbContext pooling feature is very different from registering DbContext as singleton, because:
The pooling mechanism ensures that parallel requests get their own DbContext instance.
Therefore, multiple DbContext instances exist with pooling, while only a single instance for the whole application exists when using the Singleton lifestyle.
Using the singleton lifestyle, therefore, ensures that one single instance is reused, which causes the myriad of problems laid out (again) here.
The pooling mechanism ensures that, when a DI scope ends, the DbContext is 'cleaned' and brought back to the pool, so it can be reused by a new request.
what are the impacts of using the DbContextPool instead of the DbContext?
More information about this is given in this document.
when we should use it and what should be considered when we use contextPool?
When your application requires the performance benefits that it brings. This is something you might want to benchmark before deciding to add it.
DbContextPool is thread-safe?
Yes, in the same way as registering a DbContext as Scoped is thread-safe; in case you accidentally hold on to a DbContext instance inside an object that is reused accross requests, this guarantee is broken. You have to take good care of Scoped objects to prevent them from becoming Captive Dependencies.
Has it memory issues because of storing a number of dbset instances throughout the application's lifetime?
The memory penalty will hardly ever be noticable. The so-called first-level cache is cleared for every DbContext that is brought back to the pool after a request ends. This is to prevent the DbContext from becoming stale and to prevent memory issues.
change-tracking or any parts of the ef would be failed or not in the DB context pool?
No, it doesn't. For the most part, making your DbContext pooled is something that only requires infrastructural changes (changes to the application's startup path) and is for the most part transparent to the rest of your application. But again, make sure to read this to familiar yourself with the consequences of using DbContext pooling.
In our application architecture, we use EF as an ORM to our database. When making use of asynchronous programming we came into an issue where a DBContext cannot be used by multiple threads at one time when injected through a constructor.
To circumvent this, we make use of the IServiceScopeFactory and created a scoped context of our DBContext when needed through a using () statement. This allows us to run DB calls through EF concurrently.
For tasks that do not run concurrently, we inject our DBContext in through our constructor and use that.
What is the immediate downside (if any) of using IServiceScopeFactory when programming asynchronous tasks using EF?
The method that we use can be found here: IServiceScopeFactory and EF
Thanks
The transaction model in Spring batch is not so easy to understand, therefore I wonder where spring batch really needs to have proxies to fulfill all its work.
So does Spring need to create proxies around Readers, Writers, Processors and Steps and therefore I have to inject them as beans? or is it OK to no use injection for them?
Spring only uses proxies within batch when you're using step scope. Otherwise, the beans are created and injected. With regards to not using injection for them, you can take that approach but there is a lot going on under the covers that you'd need to handle yourself so it's not recommended.
Given: simple JSF webapp (no Seam), having JSF beans calling few EJB's which in turn load and persist JPA entities. What I want to is to use #Singleton annotation for ejb's and inject EntityManager instead of EntityManagerFactory:
#Singleton
public class MyEJB {
#PersistenceContext(unitName = PERSISTENCE_UNIT_NAME)
protected EntityManager em; // not EntityManagerFactory
}
Spec says that #Singleton is thread-safe, supports concurrency and transaction attributes which (from my pov) makes it safe for calling from JSF beans. I expect also performance benefits because of EntityManager not being recreated for each call and it's internal caching abilities.
My main concern here is create/update operations on JPA entities in the situation when I have several singletons and, as a result, the same count of long-living EntityManagers.
What happens if one singleton updates an JPA instance and how these
changes are populated to other singletons?
As I'm not able to close entity manager, do I need to flush it upon
each entity update?
Would it be better if these few singletons will share the same entity
manager?
I saw only few examples of such design. Why? Are there any serious
drawbacks?
Many thanks in advance!
I expect also performance benefits because of EntityManager not being recreated for each call and it's internal caching abilities.
You might save some memory using singletons, but using it everywhere in your app could make it actually slower, because as there's only one EJB to serve all the concurrent requests by various users of your app, the container locks access to the EJB and when it's busy serving a request it cannot be serving another request. However this can be alleviated to some degree using lock types (i.e. #Lock(WRITE) and #Lock(READ)).
Singletons are useful for times when you want to execute a piece of code periodically using EJB timers, or to update a cache periodically, etc.
What happens if one singleton updates an JPA instance and how these changes are populated to other singletons?
Shouldn't be any different to the way non-singleton EJBs behave.
As I'm not able to close entity manager, do I need to flush it upon each entity update?
If you use CMT, no. At the end of each transaction everything will be flushed automatically.
Would it be better if these few singletons will share the same entity manager?
Looks like premature optimization to me. Just let the container inject the EM for you.
I saw only few examples of such design. Why? Are there any serious drawbacks?
Already explained.
There is one thing I want to mention regarding changing LockType of Singleton EJBs. While in general it sounds like a good idea, you should remember that resources such as EntityManger are NOT thread-safe, so appropriate concurrent access control should be provided. You can annotate methods that access non-thread-safe resources with #Lock(WRITE), but if almost all interface methods of your Singleton EJB access such resources, you will have almost the same situation as with fully write locked one. Alternative is to use Bean Concurrency Management with manual fine-grained synchronization, but it's also questionable decision.
Because of this in general I prefer Stateless EJBs over Singleton and use latter in specific cases.
Is there a way I can have Spring inject dependencies on construction of an object at runtime, rather than when parsing the Spring XML files or on package-scan?
I've got some objects that extend Thread and do file transfers. It be nice to have the services these Thread sublasses depend on autowired, so I don't have to pass them all in the constructor.
BONUS QUESTION!
Is there anything I need to do with these Thread subclasses once they've done their run() implementation has finished? Do they need 'killing' somehow?
I'd use the Spring injection facilities as is. You can inject a ThreadPoolTaskExecutor and let your objects use that. No Threads will be killed or harmed by your application: Spring will manage them all.