我正在使用Spring注释来管理我的事务,如下所示:
@Transactional(readOnly = true) public class AlertServiceImpl implements AlertService { private AlertDAO alertDAO; public List<Alert> getAlerts(){ List<Alert> alerts = alertDAO.getAlerts(); return alerts; } }
我想知道如果忘记注释会发生什么:
// Oops! Forgot to use transactional annotation public class AlertServiceImpl implements AlertService { private AlertDAO alertDAO; public List<Alert> getAlerts(){ List<Alert> alerts = alertDAO.getAlerts(); return alerts; } }
当alertDAO实现如下时:
import org.springframework.orm.hibernate3.support.HibernateDaoSupport; // no annotation here either public class HibernateAlertDAO extends HibernateDaoSupport implements AlertDAO { public List<Alert> getAlerts(){ // some implementation details that define queryString Query query = getSession().createQuery(queryString); List<Alert> alerts = query.list(); return alerts; } }
似乎Hibernate允许我从数据库中获取数据,即使没有注释也是如此。
这种粗心大意的后果是什么?可能发生的最坏情况是什么?
根据文档(Spring docs),它仅仅是元数据,它表明方法或接口可以由“具有交易意识的”事物(例如<tx:annotation- driven/>)进行配置。
<tx:annotation- driven/>
相信只有 tx:annotation驱动 并且没有@Transactional属性,我相信您可以应用“默认”事务性:
@Transactional
假设您使用的<tx:annotation-driven />是通过事务管理器来驱动它,那么缺少该@Transactional属性意味着您无法应用诸如 readOnly , isolation , propagation , propagation , rollbackFor , noRollbackFor 等 属性 。
<tx:annotation-driven />
我相信MVC稍有不同-Hibernate会话直接与MVC请求绑定-即,当收到请求时,事务开始。
回到您的示例,HibernateDAOSupport中的getSession()的代码如下:
protected final Session getSession() throws DataAccessResourceFailureException, IllegalStateException { return getSession(this.hibernateTemplate.isAllowCreate()); }
依次调用:
/** * Obtain a Hibernate Session, either from the current transaction or * a new one. The latter is only allowed if "allowCreate" is true. *....... */ protected final Session getSession() throws DataAccessResourceFailureException, IllegalStateException { return getSession(this.hibernateTemplate.isAllowCreate()); }
最终要求:
/** * .... * @param allowCreate whether a non-transactional Session should be created * when no transactional Session can be found for the current thread * .... */ private static Session doGetSession( SessionFactory sessionFactory, Interceptor entityInterceptor, SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate)
从根本上讲,Transaction:Session绑定为1:1 AFAIK,并且没有事务运行的唯一方法是使用说JBoss,它具有“嵌入”持久层,为您(在幕后)提供了事务性。即使您在调用getQuery()之后getSession()仍然有效地发生了事务,因为它是JDBC / Hibernate连接。
getQuery()
getSession()