问题描述
我正在使用 Spring 注释来管理我的事务,如下所示:
I'm using Spring annotations to manage my transactions like so:
@Transactional(readOnly = true)
public class AlertServiceImpl implements AlertService {
private AlertDAO alertDAO;
public List<Alert> getAlerts(){
List<Alert> alerts = alertDAO.getAlerts();
return alerts;
}
}
我想知道如果我忘记了注释会发生什么:
I'm wondering what happens if I forget the annotation:
// 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 实现如下:
When the alertDAO implementation is following:
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 允许我在没有注释的情况下从数据库中获取数据.
It seems like Hibernate allows me to fetch data from database even without the annotation.
这种粗心大意的后果是什么?可能发生的最坏情况是什么?
What are the consequences of this kind of carelessness and what are the worst case scenarios that could happen?
推荐答案
根据文档(Spring 文档)它只是元数据,表明方法或接口可以通过事务感知"的东西进行配置(即 <tx:annotation-driven/>
).
According to the documentation (Spring docs) it's just metadata to give an indication that the method or interface can be configured by something that is 'transactionally aware' (i.e. <tx:annotation-driven/>
).
仅使用 tx:annotation-driven 而没有 @Transactional
属性,我相信您会应用默认"事务性:
With just tx:annotation-driven and no @Transactional
attribute I believe you get the "default" transactionality applied:
- 传播设置必需.
- 隔离级别为默认.
- 事务是读/写的.
- 事务超时默认为底层事务系统的默认超时,如果不支持超时,则无.
- 任何 RuntimeException 都会触发回滚,而任何检查的 Exception 都不会.
- Propagation setting is REQUIRED.
- Isolation level is DEFAULT.
- Transaction is read/write.
- Transaction timeout defaults to the default timeout of the underlying transaction system, or none if timeouts are not supported.
- any RuntimeException triggers rollback, and any checked Exception does not.
假设您使用 <tx:annotation-driven/>
通过事务管理器驱动它,然后错过 @Transactional
属性意味着您可以不应用诸如 readOnly、isolation、propagation、rollbackFor、noRollbackFor 之类的属性等
Assuming you're using the <tx:annotation-driven />
to drive it via a transaction manager then missing out the @Transactional
attribute means you can't apply such properties as readOnly, isolation, propagation, rollbackFor, noRollbackFor etc.
我相信 MVC 略有不同 - Hibernate 会话直接绑定到 MVC 请求 - 即当收到请求时,事务开始.
I believe that MVC is slightly different - the Hibernate session is tied directly to the MVC request - i.e. when the request is received the transaction starts.
回到你的例子,HibernateDAOSupport中getSession()的代码如下:
Back to your example, the code for getSession() in HibernateDAOSupport is as follows:
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)
从根本上说,一个事务:会话是 1:1 AFAIK 绑定的,没有事务运行的唯一方法是使用 JBoss,它有一个烘焙"持久层,为您提供事务性(在幕后).即使你在 getSession()
之后调用 getQuery()
你仍然有效地有一个事务发生,因为它是一个 JDBC/Hibernate 连接.
Fundamentally, a Transaction:Session is tied 1:1 AFAIK, and the only way to run without a transaction is by using say JBoss which has a 'baked in' persistence layer which provides the transactionality for you (under the covers). Even if you call getQuery()
after getSession()
you still effectively have a transaction occurring as it's a JDBC/Hibernate connection.
这篇关于Spring 管理的事务没有@Transactional 注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!