当前位置: 首页 > 面试题库 >

没有@Transactional批注的Spring托管事务

薛扬
2023-03-14
问题内容

我正在使用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驱动 并且没有@Transactional属性,我相信您可以应用“默认”事务性:

  • 传播设置是 必需的
  • 隔离级别为 DEFAULT
  • 事务是读/写。
  • 事务超时默认为基础事务系统的默认超时,如果不支持超时,则默认为无。
  • 任何 RuntimeException都会 触发回滚,而任何选中的 Exception 都不会触发。

假设您使用的<tx:annotation-driven />是通过事务管理器来驱动它,那么缺少该@Transactional属性意味着您无法应用诸如
readOnlyisolationpropagationpropagationrollbackFor
noRollbackFor属性

我相信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连接。



 类似资料:
  • 问题内容: 这与Spring 在服务层上使用 注释有关。 我经历了很多关于此的堆栈溢出问题,但是仍然对是否应该避免使用感到困惑。 如果有人帮助我找出以下查询的答案,那将是很大的帮助。 在具有复杂模式的应用程序中使用是不好的做法。 使用此过滤器可能会导致问题 如果我们正在使用,是否意味着不需要? 下面是我的Spring配置文件 问题答案: 是一个servlet过滤器,而不仅仅是打开一个hiberna

  • 问题内容: 我正在阅读使用Spring框架进行的事务管理。在第一个组合中,我使用了Spring + hiberante,并使用了Hibernate的API来控制事务(Hibenate API)。接下来,我想使用注释进行测试,它确实起作用。 我对此感到困惑: JPA,JTA,Hibernate是否具有它们自己的事务管理方式。例如,考虑如果我使用Spring + Hibernate,在那种情况下您会使

  • 问题内容: 使用Spring(3.0.5),Hibernate(3.6.0)和Wicket(1.4.14)开发应用程序时遇到了一个奇怪的问题。问题是:我无法将任何对象保存或修改到数据库中。“不能”是指对象的所有更改或对EntityManager.persist(foo)的调用都被简单,无声地忽略。选择工作。 示例案例很简单-在某些检票页面上,我尝试将对象保存到数据库中,如下所示 这是comicDA

  • 问题内容: 我知道从同一个类内部调用事务方法时,它不会在事务中运行。Spring为事务方法创建代理,并将它们包装在try- catch块中,如果发生异常,则回滚。请考虑以下情形: 假设已从另一个对象调用,并且中发生了异常,因此成功完成但未成功。据我所知,尽管并且不是事务性的(因为它们是从同一个对象中调用的),但由于它是事务性的,因此仍应回滚。 我不明白的是,为什么人们说自我调用会破坏交易?只要调用

  • 嗯,在这个问题上我可能是错的,但是我需要你的宝贵意见/建议来站在正确的道路上。 我想知道在和中处理事务管理的好的、更好的、最好的方法,以及每种方法的优缺点。 我知道的一些方案/方法也是如此: 1) 使用AOP注释的Spring事务管理(,,带有诸如,,等建议)。 问题1:我之前用SpringAOP做了一个日志示例,但我不知道如何在事务管理中做同样的事情。事务是否会在该方面类中启动、回滚和提交,并提

  • 我有几个spring批处理作业,如果在spring批处理中触发作业执行,这些作业可以正常工作。这些作业将使用JpaItemWriter对数据库进行读写,其中需要事务。 我的问题是,我有一个quartz调度器,它被配置为定期运行这些作业,我得到了“javax.persistence.TransactionRequiredException:无事务正在进行”错误。我知道目前quartz正在实例化作业b