@transactional注解应添加在service层
使用声明式事务管理@transactional注解式,需要使用getCurrentSession来开启session,
而使用 openSession() 事物不会提交
另外,getCurrentSession是和事物相关的,如果不开启事务,单纯的使用它,
也会报错:Could not obtain transaction-synchronized Session for current thread
@Service("stuServiceImpl")
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public class StuServiceImpl implements StuService {
@Autowired(required=false)
private StuDaoImpl stuDaoImpl;
}
public void saveAll(Student s, Score ss) {
System.out.println(" enter StudaoImpl.addAll");
// 在使用事物声明式事务管理(即:@Transactional),应使用getCurrentSession,
// 而不能使用openSession,否则事物不会提交
//另外,getCurrentSession是和事物相关的,如果不开启事务,单纯的使用它,
//也会报错:Could not obtain transaction-synchronized Session for current thread
// Session session = sessionFactory.openSession();
Session session = sessionFactory.getCurrentSession();
session.save(s);
session.save(ss);
}
附:getCurrentSession源码
/**
* Retrieve the Spring-managed Session for the current thread, if any.
*/
@Override
public Session currentSession() throws HibernateException {
Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
if (value instanceof Session) {
return (Session) value;
}
else if (value instanceof SessionHolder) {
SessionHolder sessionHolder = (SessionHolder) value;
Session session = sessionHolder.getSession();
if (!sessionHolder.isSynchronizedWithTransaction() &&
TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(
new SpringSessionSynchronization(sessionHolder, this.sessionFactory, false));
sessionHolder.setSynchronizedWithTransaction(true);
// Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
// with FlushMode.MANUAL, which needs to allow flushing within the transaction.
FlushMode flushMode = session.getFlushMode();
if (flushMode.equals(FlushMode.MANUAL) &&
!TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
session.setFlushMode(FlushMode.AUTO);
sessionHolder.setPreviousFlushMode(flushMode);
}
}
return session;
}
if (this.transactionManager != null) {
try {
if (this.transactionManager.getStatus() == Status.STATUS_ACTIVE) {
Session session = this.jtaSessionContext.currentSession();
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(new SpringFlushSynchronization(session));
}
return session;
}
}
catch (SystemException ex) {
throw new HibernateException("JTA TransactionManager found but status check failed", ex);
}
}
if (TransactionSynchronizationManager.isSynchronizationActive()) {
Session session = this.sessionFactory.openSession();
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
session.setFlushMode(FlushMode.MANUAL);
}
SessionHolder sessionHolder = new SessionHolder(session);
TransactionSynchronizationManager.registerSynchronization(
new SpringSessionSynchronization(sessionHolder, this.sessionFactory, true));
TransactionSynchronizationManager.bindResource(this.sessionFactory, sessionHolder);
sessionHolder.setSynchronizedWithTransaction(true);
return session;
}
else {
throw new HibernateException("Could not obtain transaction-synchronized Session for current thread");
}
}