问题
I'm trying to get a better handle on the use of Spring's @Transactional
attribute. I understand that it basically wraps the contents of the method marked as @Transactional
in a transaction. Would it be appropriate to mark a service/business layer method as transactional, as opposed to the actual DAO method, as I have done here?
Service Implementation
public class UserServiceImpl implements UserServiceInt{
@Autowired
private UserServiceDAO serviceDAO;
@Override
public User getUser(int id){
return serviceDAO.getUser(id);
}
@Override
@Transactional
public void updateUserFirstName(int id, String firstName) throws SomeException{
User userToUpdate = getUser(id);
if(userToUpdate == null){
throw new SomeException("User does not exist");
}
userToUpdate.setFirstName(firstName);
serviceDAO.updateUser(userToUpdate);
}
}
DAO Implementation
public class UserServiceDAOImpl implements UserServiceDAOInt{
@PersistenceContext(unitName="myUnit")
private EntityManager entityManager;
@Override
public void updateUser(User user){
entityManager.merge(user);
}
}
I'm not even sure if the call to merge is even necessary. How does Spring know which EntityManager to use since there isn't an EntityManager declare in the UserServiceImpl class?
回答1:
We mark a Service layer with @Transactional
when a method in a Service class is having multiple database calls and we want either all calls should happen or no one should happen or we can say if any call fail then whole transaction should rollback
. If we are not falling under this criteria then we can opt for @Transactional
on DAO layer also.
How does Spring know which EntityManager to use since there isn't an EntityManager declare in the UserServiceImpl class?
Spring is referring the EntityManager
from persistence.xml
(from classpath), whose structure is similar to below:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="myUnit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/YourDatasource</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
来源:https://stackoverflow.com/questions/30667972/spring-transactional-annotation