I'm looking at performance issues with a Grails application, and the suggestion is to remove the transactions from the services.
Is there a way that I can measure the change in the service?
Is there a place that has data on how expensive transactions are? [Time and resource-wise]
If someone told you that removing transactions from your services was a good way to help performance, you should not listen to any future advice from that person. You should look at the time spent in transactions and determine what the real overhead is, and find methods and entire services that are run in transactions but don't need to be and fix those to be nontransactional. But removing all transactions would be irresponsible.
You would be intentionally adding sporadic errors in method return values and making your data inconsistent, and this will get worse when you have a lot of traffic. A somewhat faster but buggy app or web site is not going to be popular, and if this doesn't help performance (or not much) then you still have to do the real work of finding the bottlenecks, missing indexes, and other things that are genuinely causing problems.
I would remove all #Transactional annotations and database writes from all controllers though; not for performance reasons, but to keep the application tiers sensible and not polluted with unrelated code and logic.
If you find one or more service methods that don't require transactions, switch to annotating each transactional method as needed but omit the annotation at class scope so un-annotated methods inherit nothing and aren't transactional. You could also move those methods to non-transactional services.
Note that services are only non-transactional if there are no #Transactional annotations and there is a transactional property disabling the feature:
static transactional = false
If you don't have that property and have no annotations, it will look like it's ok, but transactional defaults to true if not specified.
There's also something else that can help a lot (and already does). The dataSource bean is actually a proxy of a proxy - one proxy returns the connection from the pool that's a being used by an open Hibernate session or transaction so you can see uncommitted data and do your queries and updates in the same connection. The other is more related to your question: org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy which has been in Spring for years but only used in Grails since 2.3. It helps with methods that start or participate in a transaction but do no database work. For the case of a single method call that unnecessarily starts and commits an 'empty' transaction, the overhead involved includes getting the pooled connection, then calling set autocommit false, setting the transaction isolation level, etc. All of these are small costs but they add up. The class works by giving you a proxied connection that caches these method calls, and only gets a real connection and invokes these method on it when a query is actually run. If there are no queries and the only calls are those transaction-related setup methods, there's basically no cost at all. You shouldn't rely on this and should be intentional with the use of #Transactional annotations, but if you miss one this pool proxy will help avoid unnecessary work.
Related
I have been seeing this trend recently with some Spring Framework developers. When they create their Service classes they are not creating interfaces for them to implement and they are not using #Transactional in their service classes when they are definitely in need of transactions.
Is there a good reason for this?
And one more question, Spring Boot has Session In View set to be true. Why? I always thought that to be a really bad design, allowing for developers to be lazy and allow for N+1 queries to happen all the time and slowing down performance. If you know you are going to need it for the UI, why not query for it in the Service-Repository classes in the least amount of queries instead?
It's true that building Services with interfaces and class implementations has been under questioning lately. There a classic post about this: https://octoperf.com/blog/2016/10/27/impl-classes-are-evil/ .
About Transactions, for read operations the readOnly=true parameter should be included in the #Transactional annotation to make sure it is done properly. As for the write operations, of course the transaction management should be done with care and the #Transactional annotation is there to make sure it is done so. Not using it is certainly a code smell, since a transaction will happen nonetheless, but you just won't have control over it.
Session In View set to true is a code smell too, and it should be used in learning environments or short-term experiments only. Batching, among other possibilities, can and should be used to avoid the N+1 problem.
I am very new to reactive programming, and currently working on microservice where in spring mvc is used and Spring Data MongoDb for database connectivity.
As I am going through spring data mongo db docs, there is support for reactive repositories, reative template api etc.
So Is there going to be any downside if I choose to use reactive templates and repository with blocking nature ?
Ex.
reactiveMongoTemplate.add(entity).block()
reactiveMongoTemplate.update(id, entity).block()
Also is there any significant difference with using calls like above than using blocking repository and template api itself ?
The answer depends on which stack you use: Spring WebFlux or Spring Web MVC.
In case of Spring WebFlux the choice is obvious: you have to use ReactiveMongoTemplate and never call block on it, instead return Mono/Flux as you get it from the template.
In case of Spring Web MVC you are free to use both the regular blocking MongoTemplate and ReactiveMongoTemplate with block. Although, in most cases you should go with the good old MongoTemplate for sake of simplicity and performance. ReactiveMongoTemplate has some overhead compared to the blocking MongoTemplate because the reactive types Mono/Flux put some additional pressure on memory.
I can imagine one use case where ReactiveMongoTemplate can provide some advantage even in Spring MVC: when during one HTTP request you have to execute multiple Mono operations concurrently. If you used blocking MongoTemplate then you would need to set up a thread pool and delegate the query execution there. However, with ReactiveMongoTemplate you could use the many operators of Mono and Flux to accomplish this task without worrying about threads, thread pools and scaling issues.
In the traditional programming you usually own the thread that you're running on, in the reactive programming its not the case. This "underlying unit of execution" (cpu resources consumer if you wish) is not yours, but rather a "global" thing that currently happens to execute your task, but can switch to do other things really soon.
So when you block, you say to this "global unit of execution" like "hey, stop doing anything else, wait for me". In the traditional approach, its kind of ok, because you have a thread associated with the current request, other requests (or flows if your system is not web based) are supposed to be executed with other threads taken from a fairly large thread pool. In the reactive system however, its not the case since you're trying to utilize a small amount of these "global units of execution".
Ok, so if you block, the events all over the place will stop emitting and will get start to buffer. And this may lead to the whole system becoming unusable.
I am using spring boot, and it's very easy to integrate spring cache with other cache component.
By caching data, we can use #Cachable annotation, but still we need configure and add cacheName to the cacheManager, without this step, we will get an exception while accessing the method:
java.lang.IllegalArgumentException: Cannot find cache named 'xxxx' for Builder
My question is, is that able to disable the cache instead of raising the error if we not configure the cacheName? I raised this because spring cache provide a configuration spring.cache.cacheNames in CacheProperties.
Not sure if the condition attribute in #Cachable works for this.
Any idea is appreciate!! Thanks in advance!
It really depends on your "caching provider" and the implementation of the CacheManager interface, in particular. Since Spring's Cache Abstraction is just that, an "abstraction" it allows you to plugin different providers and backend data stores to support the caches required by your application (i.e. as determined by Spring's caching annotations, or alternatively, the JSR-107-JCache annotations; see here).
For instance, if you were to use the Spring Framework's provided ConcurrentMapCacheManager implementation (not recommended for production except for really simple UCs), then if you choose to not declare your caches at configuration/initialization time (using the default, no-arg constructor) then the "Caches" are lazily created. However, if you do declare your "Caches" at configuration/initialization time (using the constructor accepting cache name arguments), then if your application uses a cache (e.g. #Cacheable("NonExistingCache")) not explicitly declared, then Exception would be thrown because the getCache(name:String):Cache method would return null and the CacheInterceptor initialization logic would throw an IllegalArgumentException for no Cache available for the caching operation (follow from the CacheIntercepter down, here, here, here, here and then here).
There is no way to disable this initialization check (i.e. throw Exception) for non-existing caches, currently. The best you can do is, like the ConcurrentMapCacheManager implementation, lazily create Caches. However, this heavily depends on your caching provider implementation. Obviously, some cache providers are more sophisticated than others and creating a Cache on the fly (i.e. lazily) is perhaps more expensive and costly, so is not supported by the caching provider, or not recommended.
Still, you could work around this limitation by wrapping any CacheManager implementation (of your choice), and delegate to the underlying implementation for "existing" Caches and "safely" handle "non-existing" Caches by treating it as a Cache miss simply by providing some simple wrapper implementations of the core Spring CacheManager and Cache interfaces.
Here is an example integration test class that demonstrates your current problem. Note the test/assertions for non-existing Caches.
Then, here is an example integration test class that demonstrates how to effectively disable caching for non-existing Caches (not provided by the caching provider). Once again, note the test/assertions for safely accessing non-existing Caches.
This is made possible by the wrapper delegate for CacheManager (which wraps and delegates to an existing caching provider, which in this case is just the ConcurrentMapCacheManager again (see here), but would work for any caching provider supported by Spring Cache Abstraction) along with the NoOpNamedCache implementation of the Spring Cache interface. This no-op Cache instance could be a Singleton and reused for all non-existing Caches if you did not care about the name. But, it would give you a degree of visibility into which "named" Caches are not configured with an actual Cache since this most likely will have an impact on your services (i.e. service methods without caching enabled because the "named" cache does not exist).
Anyway, this may not be one you exactly want, and I would even caution you to take special care if you pushed this to production since (I'd argue) it really ought to fail fast for missing Caches, but this does achieve what you want.
Clearly, it is configurable and you could make it conditional based on cache name or other criteria, in that, if your really don't care or don't want caching on certain service methods in certain contexts, then it is up to you and this approach is flexible and completely give you that choice, if needed.
Hope this gives you some ideas.
Our project is designed in EJB 2.0.
We are not using any kind of EJB persistance methods in the BMP EntityBeans. In SessionBeans we are getting reference to EntityHome object by using method getEJBXXXXHome() method and there by calling home.findByPrimaryKey("") method to get the EJB reference. Then we are calling actual methods for CRUD operations. In CRUD operations methods our people have used normal JDBC API methods.
Now we are migrating to EJB3. As part of migration from EJB 2.0 TO EJB3 am converting all my BMP EntityBeans to normal Java classes i.e there are no more entitybeans. If EJB container maintains a pool for the entitybeans earlier, it wont be there now. Its working normally when I have tested in my local machine for one transaction
My concern is, will it affects the perfromance for multiple threads in production?.
Afer changing the code now, every call creates one EntityBean Object. If 60k calls were made in just one hour will that affect my server. How this one is handled previously in EJB 2.0? is there any way to handle it in the changed code (i.e for normal java classes as they are no more entitybeans concept)
Generally speaking, the overhead of objection creation/collection is going to be lower than the overhead of whatever the EJB container was doing for your entities previously. I suspect a larger concern than object creation overhead is round-trips to the database. Depending on your EJB container configuration, it's likely the container was optimizing the JDBC SQL and possibly caching the retrieved data (unrelated to object caching). You should likely design your application to minimize calls to the database and ensure you don't execute unnecessary queries.
Ultimately, I suspect only you are going to be able to assess the performance of your application on your application server on your hardware. I recommend following good programming practices to avoid egregious overhead, profile the result, and optimize from there rather than worrying about the performance up-front.
Here's my situation. I have a class called somethingDao that contains all my logic for querying a table.
Then, I also have somethingDaoResource, which is a Jersey API resource, but also a Singleton, and is instantiating a somethingDao object via Spring (i.e., I'm injecting a datasource into somethingDao).
Then, I have a Jersey API businessLogicResource that does:
somethingDaoResource.getInstance().getsomethingDao() which gets me the somethingDao object at which I then fire multiple queries.
My question is, is this considered a good design? My main concern is that every time someone sends a HTTP request to my businessLogicResource, if the somethingDaoResource wasn't a Singleton (or a static?), then that would create a new instance of somethingDao, and open a new connection, which takes a while to do.
Any suggestions are more than welcome.
PS - I also have a c3p0 connection pool.
The most common practice is to have DAO objects as stateless singletons. Instead of opening and closing a connection they would borrow one from a pool and then return it when done. You can limit the maximum number of connections in the pool.
Having something statefull and a singleton in a web application is usually a bad idea. It might cause all kinds of read/write conflicts or thread locking. This approach also kills any possibility of distributing your application over a number of servers, which breaks one of the REST architectural constraints.