I read in this link that it is possible to use #Transactional in the service layer
Well, if we have several databases, then it is possible to use a single transaction for all of them? After all, isn't every transaction in each database specific to that database? So how can it be shared among all of them?
Related
I have configured two databases. One for read (Read-Only), other for Read-Write operations. I have service which involves both read and write operations. I would like to use the read-only db for all read operations and the other db for write operations. How could I achieve this with Spring transactions. I've implemented annotation based approach which changes the datasource using AbstractRoutingDataSource. But, everytime I need to create a new transation using propogation=Requires_New. Is there a better way to do this?
#DbSource(DbType.READ_REPLICA)
#Transactional(propogation=Requires_New)
public Object readData(long id) {
return dataDao.find(id);
}
You should create seperate spring configurations for both of your datastores together with TransactionManager beans. At least one of these beans should have name value so you can use proper transactional manager when needed:
#Transactional(transactionManager="DS1transactionManagerBeanName")
// DS1dataStoreRelevant class/method
Of course combining logic which uses both data stores in single transaction is not possible with JpaTransactionManager. If this is what you are looking for you should consider using distributed JtaTransactionManager provided by web container like IBM WebSphere or other like Atomikos/Bitronix etc. which provides you with transactionality between different data stores (XA resources in general).
Some possible workaround in certain cases (like Oracle datastores) would be to provide visibility from one database to other and use single data store/transaction manager but I am not entirely sure how it works underneath on the database side.
The most basic solution would be just to not mix logic impacting each of the data store and arrange it in sequential transactions but as said whole chain of operations won't be transnational itself so possible rollback would apply only to current transaction (no rollback to the ones committed earlier). It would require some extra logic to introduce rollback/retry policy with dirty flags etc.
where to define transaction boundries in java (#Service or #DAO level), Any Suggestions
We need to manage transaction between multiple services.
Depending on your persistence technology some kind of transactions might be needed to persist anything at all. Thus you may want a transaction on a DAO-level for e.g. testing the DAO layer. If e.g. controllers have direct access to DAOs you'll need transactions on DAOs, too.
What you may want to do is declaring a transaction on the service-level and the DAO-level reusing a provided transaction.
Read the great spring reference on transactions as well as the spring data reference for ideas.
Usually I recommend to use Transaction in Service, but it depends on....
In case of Service,you will get ability to create batch of actions in the one transaction.
For example start transaction. read, modify more than one entities, update, delete whatever. close transaction.
I have a web application that uses Spring NamedJDBCTemplate, and all the calls to database are select statements.
In this case should i use #Transactional in my service class that calls the DAO class that inturn fires select statements to DB.
According to Transaction statergies listing 10 suggests to not use #Transactional for reads. Will i be bringing an overhead by using #Transactional and also i dont want to miss the AOP advises that i can bring in for #Transactional in future.
Yes, you should always access the database from inside a transaction. Not doing it will in fact create a transaction for every select statements.
Transactions aren't just useful for atomicity of updates. They also provide isolation guarantees. For example, (depending on the isolation level) reading the same row twice in a single transaction can return you the same data, and thus make sure you don't have incoherences in the read data. Doing it with multiple transactions won't provide any such guarantee.
I think the best way is to use #Transactional and set it as Supported not Required for such service
in this way if your service call outside a transaction it will not start a Transaction and if it calls from other service that is Transactional and already start a transaction it will participate in that transaction.
for example think that one service required to call two services in first one some data will inserted or updated and other one is just a select that return those data if these two service don't participate in single transaction the second service will not return data because the transaction start in calling service not committed yet .
When using JdbcTemplate, do I need to explicitly configure transactions?
My code layout looks like the following:
I will have a UserDao that will be injected into my UserService, and then my Controllers will make calls on methods in my UserService.
I want to keep things as simple as possible transaction wise, and I don't need multiple database calls to span a transaction.
By default, do I have to do anything in my configuration file or use a #Transaction annotation anywhere?
Now say in my controller I need to make 2 calls on my userService and accountService, could I explicitly wrap it in a transaction somehow?
userService.updateUser(user);
accountService.updateXXX(...);
Yes, JdbcTemplate is not a substitute for transaction management. You still benefit from database transactions, so userService.updateUser will operate in a database transaction, but if accountService.updateXXX fails, userService.updateUser will not rollback.
If you don't want to use AOP, you can use TransactionTemplate instead. See programmatic transaction management in the Spring Reference Documentation.
One pattern I've seen before is for the MVC controller class to invoke a business service, which encapsulates the operation. The method of the business class could then be annotated #Transactional.
If your controller wants to do several things with users and accounts and have all that happen within one transaction, then you should have a service with one method that does all that stuff. Creating one service per DAO is not a great idea, because you end up with do-nothing wrappers around DAOs and processing will be slow because the database will have to create a separate transaction for each call to a DAO, you're making it do a lot more work than it should have to.
The service should provide functionality to the controller or whoever else is calling it. I try to create services with the idea that the service provides specific functions useful to a certain type of user.
What is DAO and Service layer exactly in Spring framework?
I am looking for theoretical answer.
There is no distinction as far as Spring is concerned. By convention you can mark DAO classes with #Repository and services with #Service. Also the former does some persistence layer exception translation.
Since you are asking theoretically: DAO should perform raw database operations and translate them to some higher level constructs (objects, collections). Services should call DAOs and perform business operations. Typically transactions demarcation is performed on service layer to span several DAO calls.
Finally DAO should abstract business logic from persistence details, ideally allowing to switch persistence layer without business logic (services) changes. This is hardly ever possible due to leaking abstraction of persistence providers (e.g. lazy loading).
DAO - data access object, are object to handle connection to your data storage (typicaly database). You have here your queries and DAO provides data to your services.
Services should contain all your logic. If you have logic separete you can theoretically change your UI layer or DAO layer without you affected it.
It gives decoupling benefits. When source of data changes the way you process data in Service for all service users (mobile client, web-client) does not change. But you need to change the way you extract data from data source.
DAO(Data Access Object) is a design pattern, which consists on creating for each table on your database a class,it provides a technique for separating object persistence and data access logic