【问题标题】:spring mvc hibernate proper way of transaction managementspring mvc hibernate事务管理的正确方法
【发布时间】:2012-07-04 17:18:53
【问题描述】:

也许标题有点误导,但我想请你提个建议。

现在假设我已经为我的 spring mvc 应用程序配置了休眠和事务。部分配置如下所示:

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="oracle.jdbc.OracleDriver"/>
    <property name="jdbcUrl" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
    <property name="user" value="xxx"/>
    <property name="password" value="xxx"/>
    <property name="maxPoolSize" value="10"/>
    <property name="maxStatements" value="0"/>
    <property name="minPoolSize" value="5"/>
</bean>
<!-- Session Factory Declaration -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
    <property name="packagesToScan" value="com.execon.models"/>
</bean>

<!-- Enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/>

<!-- Transaction Manager is defined -->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

所以基本上我现在需要做的只是 @Autowired 我的 sessinFactory 到将管理数据库访问权限的类?

一个简单的例子,虽然它带有@Controller,但我会将其移至@Service

@Resource(name = "sessionFactory")
private SessionFactory sessionFactory;

@RequestMapping(value = "/")
public String getMainPage( Model model )
{
    Session session = sessionFactory.getCurrentSession();
    session.beginTransaction();
    Query query = session.createQuery( "from Period" );
    List<Period> list = query.list();
    System.out.println( list );
    session.getTransaction().commit();
    return "MainPage";
}

如您所见,我只是想将映射类的标准控制台列表放入。它工作得很好,但我需要一条建议如何在更大的项目中进行管理。我应该有一些 util 类来获取会话并开始事务吗?或者我应该使用一些模板来管理它?只是我不想写这个:

    Session session = sessionFactory.getCurrentSession();
    session.beginTransaction();
    //
    //...
    //
    session.getTransaction().commit();

在我需要连接到数据库的每个地方。也许我错过了一些东西,或者完全错了?任何帮助将不胜感激

【问题讨论】:

    标签: java hibernate spring-mvc


    【解决方案1】:

    您缺少的是 spring 事务注释。

    @RequestMapping(value = "/")
    @Transactional
    public String getMainPage( Model model )
    {
        Session session = SessionFactoryUtils.openSession(sessionFactory);
        Query query = session.createQuery( "from Period" );
        List<Period> list = query.list();
        System.out.println( list );
        return "MainPage";
    }
    

    显然,正如您所指出的,正常的事情是分离出 db 的东西。

    在您的上下文文件中,您将需要:

    <tx:annotation-driven transaction-manager="txManager" />
    

    请注意,在此特定示例中,您需要将其放入 XXX-servlet.xml 上下文文件中,因为这是配置控制器的内容。

    spring 和 hibernate 的总体思路是使用 spring 进行事务和连接管理。使用SessionFactoryUtil注册器将hibernate Session作为事务资源绑定到当前线程。

    【讨论】:

    • 请告诉我是否正确:第一个问题:@Transactional 具有类范围意味着此类中的每个方法都将使用事务处理对吗?第二个问题:通过使我的 POJO(期间类)@Transactional,我做错了什么?第三问:来自包org.springframework.orm.hibernate3getSession() 是否等于来自包org.springframework.orm.hibernate4openSession()
    • Q1 是的......您可以将整个类设置为事务性......然后在每个方法上对其进行优化。 Q2 不是特别错误.. spring 的重点是使用 POJO,使控制器的方法具有事务性并不是很好的风格,但对于一个小项目,如果你能测试它,那就见鬼了。 Q3 是的,它是一样的.. 抱歉没有选择 hibernate4 包名称...将更新答案
    猜你喜欢
    • 2012-10-16
    • 2014-07-08
    • 2016-12-02
    • 1970-01-01
    • 2012-05-06
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多