DAO and Connections - java

Where I should open and close connections to repositories? In article "Dont repeat the DAO" written:
The DAO is not responsible for handling transactions, sessions, or
connections. These are handled outside the DAO to achieve flexibility.
But some people suggest me to inject #Resource DataSource object into DAO classes and handle all connections inside DAO methods...i.e. every CRUD operation should open and close connection to repository.

Take the recommendation from the article.
Preferably you want your application container to manage Resources and connection pooling. If your connection has transaction management configured, then the container will be able to manage your transaction (hence no need to open connection and do commits).
If you're managing connection and transaction yourself, open the connection first, enable transaction and pass the opened connection to the DAO, commit transaction, then close connection (outside of the DAO).
Once your service finished with all DAO's, close the connection.
Hope this helps.

I personally use Spring to manage the data sources.
Configure the data source bean in your application context xml. Autowire it to the DAO and then use Spring to handle the transactions with the #Transactional annotation on the DAO class.
You also need <tx:annotation-driven/> in your application context.
If you are using Hibernate you can do the same by configuring the SessionFactory in your application context.

I agree that you can use spring for managing transactions but at the same time keep in mind that managing transactions is not a duty of DAOs. They should be handled in your service layer which is responsible for managing business logic.

Related

How to configure MongoDB in java without Spring to access a common connection pool? How to make a common connection to DB with singleton pattern?

I have a scenario where I need to configure the Mongo DB in Java Application. I don't use Spring, but I need to make the connection to DB as common so that whenever there is a transaction that is going to happen, it must create a connection automatically and it must close the connection when the transaction is done.
EDIT:
How to make the connection common instead of creating the instance each time when the transactions are done?
You can see an example of transactions working with Java code (and without Spring):
Article: https://www.mongodb.com/blog/post/java-and-mongodb-40-support-for-multidocument-acid-transactions
GitHub: https://github.com/MaBeuLux88/mongodb-4.0-demos

Is there a way to force Hibernate to use new connection for next transaction within a Spring application?

In Spring applications (that use Spring's declarative transaction management) when using JPA/Hibernate, when a transaction is first started within a request, Hibernate session is created and a database connection will be obtained from a datasource in order to execute this first transaction. Any subsequent transaction within the request will reuse the session and the connection. Is there a way to force Hibernate (or Spring's transaction management system) to obtain a new connection from the datasource for the subsequent transaction?
Background info and what I am trying to achieve
I'm using a custom implementation of AbstractRoutingDatasource to route database requests between a master and a replicated slave (read-only) database. I've created custom annotation with datasource routing information and AOP Aspect that intercepts the methods annotated with my custom annotation in order create a framework where one could add additional datasource routing annotation in addition to #Transactional in order to select a datasource (master or slave) on which the transaction should be executed. Aspect informs the routing datasource that next connection requested within current thread should go to a specific datasource (as defined in the annotation) before transaction starts. The problem is this only works on the first transaction because Hibernate caches connection and does not request new one for next transaction.
You will need to implement a custom ConnectionProvider. Hibernate will by default come with DriverManagerConnectionProviderImpl. However, most people end up using c3p0 (many without even knowing it), proxool, Hikari, or some other implementation.
All of these (including Hibernate's default) will cache connections (it is their primary purpose). You will probably need to create a connection provider which has a reference to two other connection providers (one per data source). The inner connection providers can be c3p0 or whatever other implementation you want to use.
This article gives a good basic overview of the concept (as well as describing what property to set to supply your own).

Transaction Management outside Data Access Layer

Data Access Layer is not responsible for transaction management am I correct? I have these DAO implementations: HibernateDAO and SqlDAO. If I will choose Hibernate and handle its transaction management at above layer, when I switch to SQL then I will change every single transaction management made by the Hibernate to SQL? This is bad right? What strategy will I gonna use in this case? TIA.
I've never worked on transactions outside of spring and JTA. Spring offers a transactions across several different platforms using transactions. You may want to check that out.
Also, I've seen JTA transactions work on ejb, Hibernate and Jms messages, but not sure if it will work for jdbc and hibernate, more on hibernate transactions here.

Begin and commit transaction in interceptor

Is it good practice to have interceptors to manage transactions?
I have a strong point though that it is equivalent to begin and commit in the action itself.
Why should I use interceptor managed transactions at all?
It's not bad practice, for example Spring framework uses aspects for 'auto-begin' and 'auto-commit' transactions using #Transactional annotation.
Why should I use interceptor managed transactions at all?
It reduces a lot of boilerplate code: opening connection, beginning transaction, committing transaction and closing connection.
But if you want to write your own transaction manager using interceptors - beware of concurrency issues
According to image you posted:
It's better not to expose transaction management from Service layer. It's better if your presentation layer don't know anything about Transaction management. So try to encapsulate your transaction management code in service layer or in DAO layer. If your presentation layer manages transaction and service layer is not, it's mean your services is not self-contained, and they can be reused by other client only if client provide some transaction management logic.
From Comments:
Better is to put transaction management code to service layer, because
service layer usually performs some business level operations, which
must be performed within one transaction. So your service method can
use 2 or more DAOs to perform all DB operations in one transaction.
Sorry, there is no links - I tell it your from my experience.

how the Transaction concept is implemented in EJB

I wan to know how the transaction is internally implemented in EJB. I want to know the logic they use to create a transaction. if you could point out some articles that would be helpful
Hibernate doesn't implement transactions, it relies on and wraps JDBC transactions or JTA transactions (either container managed or application managed).
Regarding EJBs, if you want to understand the details of a JTA Transaction Manager, you'll need to be fluent with the JTA interfaces UserTransaction, TransactionManager, and XAResource which are described in the JTA specification. The JDBC API Tutorial and Reference, Third Edition will also be useful to understand the XA part of a JDBC driver.
Then, get the sources of an EJB container (like JBoss) or of a standalone JTA Transaction Manager (like Atomikos) to analyze the TM part. And good luck.
This question could have answers at many levels.
A general discussion of what's going on can be found here
My summary goes like this ... First, somewhere there must be a transaction coordinator, the EJB container will know about the coordinator - typically that's part of the application server. So all the EJB container has to do is to call
someobject.BeginTransaction()
that's it. The actual API the EJB container uses is JTA. EJBs can actually use Bean Managed transaction transaction or Container managed transactions. In the Bean Managed case the implementer nhas to make the JTA calls. More usually we use Container Managed transactions (CMT). In which case the container has logic which is run before the implementation is reached. For example:
if ( we're not already in a transaction )
begin transaction
call the EJB implementation
and later the container has logic
if ( finished processing request )
commit transaction
with other paths to abort the transaction if errors have happened.
Now that logic is more complex because CMT EJBs are annotated with transaction control statements. For example you can say things "if we already have a transaction, use it" So if one EJB calls another only a single transaction is used. Read up the EJB spec for that.
However all that's pretty obvious in any write-up of Java EE EJBs. So I suspect that you're asking moe about what happens inside the JTA calls, how the transaction manager is implemented and its relationship to the transactional resource managers (eg. Databases). That's a huge topic. You've actually go implementations of the XA distributed transaction protocol down there. Frankly I doubt that you really need to need to know this. At some point you have trust the APIs you're using. However there is one key detail: your Transaction Manager (typically the App Server itself) must be able to tell the REsource Managers the fate of any given transaction, and that information must survive restart of the App Server, hence some persistent store of transaction information must be kept. You will find transaction logs somewhere, and in setting up the App Server you need to make sure those logs are well looked after.
From EJB in Action book
The protocol commonly used to achieve multiple resource is the two-phase commit. The two-phase commit protocol performs an additional preparatory step before the final commit. Each resource manager involved is asked if the current transaction can be successfully committed. If any of the resource managers indicate that the transaction cannot be committed if attempted, the entire transaction is abandoned (rolled back). Otherwise, the transaction is allowed to proceed and all resource managers are asked to commit.
A resource manager can be a database, for instance. Others examples includes a Message Service. The component which coordinates transactions is called Transaction manager.
Suppose you have an application which involves two distincts databases. How does Transaction manager performs its work by using Two phase commit protocol ?
Transaction Manager ask database 1 if it can commit the current transaction
If so, ask database 2 if it can commit the current transaction
Transaction Manager ask database 1 to commit
Transaction Manager ask database 2 to commit
Hibernate is built on top of the JDBC API. It just coordinates one database. So if you call
session.commit();
Behind the scenes, it call
connection.commit();
If you really want to study Transaction internals, my advice is Java Transaction Processing book.
Hibernate has TransactionFactory:
An abstract factory for Transaction instances. Concrete implementations are specified by hibernate.transaction.factory_class.
It has implementations: JDBCTransactionFactory, JTATransactionFactory, CMTTransactionFactory. These factories create an instance of Transaction - for example JDBCTransaction.
Then I can't tell you what happens for JTA and CMT, but for JDBC it's as simple as setting the auto-commit to false (when you call begin a transaction):
connection.setAutoCommit(false);
And respectively on transaction.commit(): connection.commit()
If any exception occurs when operating with the session, it invokes connection.rollback()
Another good read would be the JTS articles by Brian Goetz; links:
http://www.ibm.com/developerworks/java/library/j-jtp0305.html
http://www.ibm.com/developerworks/java/library/j-jtp0410/index.html
http://www.ibm.com/developerworks/java/library/j-jtp0514.html

Categories

Resources