Is there a better way of detecting if a Spring DB transaction is active than using TransactionSynchronizationManager.isActualTransactionActive()? - spring

I have some legacy code that I am now trying to re-use under Spring. This code is deeply nested in other code so it's not practical to redesign and is called in many situations, only some of which are through Spring. What I'd like to do is to use the Spring transaction if one has been started; otherwise, continue to use the existing (legacy) db connection mechanism. Our first thought was to make our legacy class a bean and use an injected TransactionPlatformManager, but that does not seem to have any methods germane to our situation. Some research showed that Spring has a class called TransactionSynchronizationManager which has a static method isActualTransactionActive(). My testing indicates this method is a reliable way of detecting if a Spring transaction is active:
When called via Spring service without the #Transactional annotation, it returns false
When called via Spring service with #Transactional, it returns true
In my legacy method called the existing way, it returns false
My question: Is there a better way of detecting if a transaction is active?

No better way than the TransactionSynchronizationManager.isActualTransactionActive(). It is the utility method used by spring to handle the transactions. Although it is not advisable to use it within your code, for some specific cases you should - that's why it's public.
Another way might be to use the entity manager / session / connection and check there if there's an existing transaction, but I'd prefer the synchronization manager.

Related

Spring Boot Repository [duplicate]

I have been working with Spring Data JPA repository in my project for some time and I know the below points:
In the repository interfaces, we can add the methods like findByCustomerNameAndPhone() (assuming customerName and phone are fields in the domain object).
Then, Spring provides the implementation by implementing the above repository interface methods at runtime (during the application run).
I am interested on how this has been coded and I have looked at the Spring JPA source code & APIs, but I could not find answers to the questions below:
How is the repository implementation class generated at runtime & methods being implemented and injected?
Does Spring Data JPA use CGlib or any bytecode manipulation libraries to implement the methods and inject dynamically?
Could you please help with the above queries and also provide any supported documentation ?
First of all, there's no code generation going on, which means: no CGLib, no byte-code generation at all. The fundamental approach is that a JDK proxy instance is created programmatically using Spring's ProxyFactory API to back the interface and a MethodInterceptor intercepts all calls to the instance and routes the method into the appropriate places:
If the repository has been initialized with a custom implementation part (see that part of the reference documentation for details), and the method invoked is implemented in that class, the call is routed there.
If the method is a query method (see DefaultRepositoryInformation for how that is determined), the store specific query execution mechanism kicks in and executes the query determined to be executed for that method at startup. For that a resolution mechanism is in place that tries to identify explicitly declared queries in various places (using #Query on the method, JPA named queries) eventually falling back to query derivation from the method name. For the query mechanism detection, see JpaQueryLookupStrategy. The parsing logic for the query derivation can be found in PartTree. The store specific translation into an actual query can be seen e.g. in JpaQueryCreator.
If none of the above apply the method executed has to be one implemented by a store-specific repository base class (SimpleJpaRepository in case of JPA) and the call is routed into an instance of that.
The method interceptor implementing that routing logic is QueryExecutorMethodInterceptor, the high level routing logic can be found here.
The creation of those proxies is encapsulated into a standard Java based Factory pattern implementation. The high-level proxy creation can be found in RepositoryFactorySupport. The store-specific implementations then add the necessary infrastructure components so that for JPA you can go ahead and just write code like this:
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
The reason I mention that explicitly is that it should become clear that, in its core, nothing of that code requires a Spring container to run in the first place. It needs Spring as a library on the classpath (because we prefer to not reinvent the wheel), but is container agnostic in general.
To ease the integration with DI containers we've of course then built integration with Spring Java configuration, an XML namespace, but also a CDI extension, so that Spring Data can be used in plain CDI scenarios.

Spring-Cloud, Hystrix and JPA - LazyInitializationException

I have the following problem trying to integrate Hystrix into an existent Spring Boot application. I am using boot with spring data (jpa repositories). The structure of the app is pretty simple,
we have Resources -> Services -> Repositories.
I enabled Hystrix support and annotated one of the service methods that returns an entity as follow:
#HystrixCommand(fallback="getDealsFallback")
public Page<Deal> getDeals(...) {
// Get the deals from the Index Server.
return indexServerRepository.findDealsBy(...);
}
public Page<Deal> getDealsFallback(...) {
// If IndexServer is down, query the DB.
return dealsRepository.findDealsBy(...);
}
So this works as expected, the real problem resides actually when I return the Entity to the client. I am using OpenEntityManagerInViewFilter so I can serialize my model with its relations.
When I use #HystrixCommand in my service method, I get a LazyInitializatioException when It tries to serialize.
I know the cause (or at least I suspect what is the problem), and is because Hystrix is executing in another thread
so is not part of the transaction. Changing the Hystrix isolation strategy from THREAD to SEMAPHORE, works correctly since its the same thread, but I understand that is not the correct way to approach the problem.
So my question is, How can I make the Hystrix executing thread be part of the transaction. Is there any workaround that I can apply?
Thanks!
It is a little old thread, but maybe someone meets this problems too. There is an issue in github about this.
The reason is, hystrix will run in separate thread, which is different from where the previous transaction is. So the transaction and serialization for lazy will not work.
And the 'THREAD' is the recommended execution strategy too. So if you want to use both hystrix and transaction, you should use them in 2 level calls. Like, in first level service function, use transaction, and in second level service function, use hystrix and call first level transactional function.

SimpleJDBCTemplate and AbstractDataSource configuration

I am working on an app that uses SimpleJDBCTemplate as the wrapper to make JDBC calls.
However, instead of a conventional Datasource, I am choosing to use AbstractDataSource so I can choose from multiple data sources.
I am using ThreadLocal to inject keys to choose the appropriate Datasource.
However, it appears Spring is eagerly creating all my DAOs and my jdbcTemplate and hence I cannot figure out how to have the jdbcTemplate get Connection on demand.
Any clues.?
Do you mean AbstractRoutingDataSource? If not, you really should be using that, since this is exactly what it's for. Mark Fisher wrote a useful blog about it back when it was added to the framework.
Yes Spring will create your DAOs and JdbcTemplates eagerly if they're singletons, which is the default, but that doesn't mean they all obtain a connection immediately. A connection will only be obtained when you start some kind of operation that uses that data source. Typically, that would be starting a transaction. In other words, what you say you want to happen is what already happens.

Spring transaction support in Netty handlers

I am using the following versions:
Spring 3.1.1.RELEASE
Netty 3.4.0.Final
Hibernate 3.5.6-Final
Now, I have a Netty server that works fairly well - the root of the server, the pipeline factories and the base "stub" of the server that owns everything are all set up with Spring. In this stub, spring #Transactional annotations work just fine.
However, in the handlers, which are stateful and created dynamically depending on what state the user is in - #Transactional doesn't work. I'm fairly sure I understand why. I even have a "solution" - but it's not very good.
After the decoders and encoders, I add an ExecutionHandler:
pipeline.addLast("execution", new ExecutionHandler(new OrderedMemoryAwareThreadPoolExecutor(16,1000000, 1000000)));
This appears to be where the Spring transaction support is breaking. Since Spring is unaware of these threads, it can't bind any transactions to them. The classes are proxied correctly, but in debug they have no associated transactions.
My solution is crappy, and it needs to be replaced by a real solution:
Session sess = SessionFactoryUtils.getSession(getSessionFactory(), true);
That's bad because it relies on me to release the session, and it may not even be transactional, I haven't checked. It sucks in a lot of ways.
Anyway - the root of the question. Given the above tech, what's my path to getting my #Transactional notations working on the Netty handlers?
Write an ExecutionHandler that's Spring aware?
NOTE: I can't upgrade to Hibernate 4, due to lack of compatibility with Spring-Flex, used in another project in the group. Probably the same story for the Spring version, can't remember.
I suggest you create these netty's handler inside spring container and inject the service or persistence layer into the handlers so you can have these layers independence from netty and of course these are old school spring beans.

Springs Transaction Management - Understanding Spring Reference, Global/Local, Programmatic/Declarative - Two Questions

Im working with the Spring Framework 3.0.5 and the Hibernate Framework and Im starting to use now Springs Transactionmanagement. I have some questions, just to understand how Springs Transactionmanagement works.
1)
I read this things in the Spring reference:
a) Consistent programming model across different transaction APIs such as Java Transaction API (JTA), JDBC, Hibernate, Java Persistence API (JPA), and Java Data Objects (JDO).
b) Spring resolves the disadvantages of global and local transactions. It enables application developers to use a consistent programming model in any environment. You write your code once, and it can benefit from different transaction management strategies in different environments.
c) Gone are the days when the only alternative to using EJB CMT or JTA was to write code with local transactions such as those on JDBC connections, and face a hefty rework if you need that code to run within global, container-managed transactions. With the Spring Framework, only some of the bean definitions in your configuration file, rather than your code, need to change.
From a) I understand that I can use those APIs with Spring without changing the code
From b) I understand that I can use global or local transactions *without changing the code
From c) I understand that while switching between different APIs and global/local transactions I need to change the code
Now I wonder what is correct?
=> Do I need to change the code? When switching between different APIs? When switching between local and global transactions? (Or does it maybe depend on prorgammatic and declarative transaction management?)
2)
I also got an additional question: I really wonder what the use of programmatic transaction management is? Everywhere I read that declarative transactionmanagement is recommended
I read this in spring reference too:
d) With programmatic transaction management, developers work with the Spring Framework transaction abstraction, which can run over any underlying transaction infrastructure. With the preferred declarative model, developers typically write little or no code related to transaction management, and hence do not depend on the Spring Framework transaction API, or any other transaction API.
From d) I understand: with programmatic transaction management I can use any underlying transaction infrastructure... which means what? the different APIs mentioned above?
and: with declarative I do not depend on any api
=> isnt this the same? when I can use any underlying api, I do not depend on any api. I do not really understand this.
where is the difference? I only know that the declarative transaction management is more lightweight, that I have not to start the transaction by my self and catch the exception and handle it and so on. But what is the use of programmatic transaction management then?
Thank you for answering! :-)
You're over-thinking this a bit. The Spring API provides an abstract transaction model that has the same API and semantics regardless of which underlying transaction technology you use. In order to switch from one technology to another, you generally have to alter your Spring config, but the idea is that you never needs to to alter your business logic. So whether you're using local, in-VM JDBC transactions or fully distributed, two-phase-commit XA JPA-style transactions, the API usage within your Spring code is the same. Only the configuration changes.
The difference between declarative and programmatic transaction management is that with the former, you use annotations or XML config to say which bits of code are supposed to be transactional. With programmatic style, you specifically enclose transactional logic using method calls into the Spring API. Note that if you use the declarative style, then Spring will wrap your code in generated logic which uses the programmatic style. The latter is simply a more explicit and low-level version of the former. It gives you more control, but it's more verbose.

Resources