【问题标题】:Spring Transactions in different DAOs does not work anyway?不同 DAO 中的 Spring Transactions 无论如何都不起作用?
【发布时间】:2009-10-28 07:23:15
【问题描述】:

这是我的实现总结

1) 所有使用 HibernateDAO 实现的 DAO 支持/@Transational 注解仅用于服务层

2) 使用 MySQL/HibernateTransactionManager

3) 使用 main(String args[]) 方法进行测试(使用此方法进行事务是否有效?)

事务不会回滚,并且可以在数据库中看到无效条目。 我在这里做错了什么?

详细信息如下。

1)我在服务层使用@Transactional注解配置事务为:

@Transactional(readOnly=false, rollbackFor={DuplicateEmailException.class,DuplicateLoginIdException.class,IdentityException.class},propagation=Propagation.REQUIRES_NEW)
    public void createUserProfile(UserProfile profile)
            throws DuplicateEmailException, DuplicateLoginIdException,
            IdentityException {

        //Accessing DAO (implemented using HibernateDAOSupport)
                identityDAO.createPrincipal(profile.getSecurityPrincipal());
        try {
                //Accessing DAO
            userProfileDAO.createUserProfile(profile);
        } catch (RuntimeException e) {
            throw new IdentityException("UseProfile create Error", e);
        }

    }

2) 我的事务管理器配置/数据源如下:

<bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url"
            value="jdbc:mysql://localhost:3306/ibmdusermgmt" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="defaultAutoCommit" value="false"/>      
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />     
        <property name="mappingLocations"
            value="classpath*:hibernate/*.hbm.xml" />
        <property name="hibernateProperties">
                <prop key="hibernate.dialect">
                org.hibernate.dialect.MySQLDialect
                </prop>             
                <prop key="hibernate.query.substitutions">
                    true=1 false=0
                </prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.use_outer_join">false</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

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

3) 使用 main() 方法测试如下:

public static void main(String[] args) {

        ApplicationContext cnt=new ClassPathXmlApplicationContext("testAppContext.xml");
        IUserProfileService upServ=(IUserProfileService)cnt.getBean("ibmdUserProfileService");

        UserProfile up=UserManagementFactory.createProfile("testlogin");//      
        up.setAddress("address");
        up.setCompany("company");
        up.setTelephone("94963842");
        up.getSecurityPrincipal().setEmail("security@email.com");
        up.getSecurityPrincipal().setName("Full Name");
        up.getSecurityPrincipal().setPassword("password");
        up.getSecurityPrincipal().setSecretQuestion(new SecretQuestion("Question", "Answer"));

        try {
            upServ.createUserProfile(up);
        } catch(Exception e){
            e.printStackTrace();
        }

【问题讨论】:

    标签: java mysql spring hibernate transactions


    【解决方案1】:

    据我所知,MySQL的默认存储引擎MyISAM does not support transactions

    MySQL 服务器(版本 3.23-max 和所有版本 4.0 及以上)支持使用 InnoDB 和 BDB 事务存储引擎的事务。 InnoDB 提供完全的 ACID 合规性。 ... MySQL 服务器中的其他非事务性存储引擎(例如 MyISAM)遵循不同的数据完整性范式,称为“原子操作”。在事务方面,MyISAM 表实际上总是在 autocommit = 1 模式下运行

    为了使事务正常工作,您必须将这些表的存储引擎切换到 InnoDB。如果您从映射中生成表 (hdm2ddl),您可能还想使用 Hibernate 的 MySQLInnodDBDialect

    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
    

    正如@gid 所提到的,这不是事务的要求。

    【讨论】:

      【解决方案2】:

      是的。您可以从main() 调用事务对象。

      @sfussenegger 是正确的,因为 MyISAM 不支持事务,使用 MySQLDialect 方言并不排除使用事务,这仅意味着 hdm2ddl 表生成将创建 InnoDB 类型的表。 (这当然可能是您的问题)。

      您能否确认您在 MySQL 中使用的是事务类型表?

      假设这是真的,接下来要做的是从org.springframework.transaction.support.AbstractPlatformTransactionManager 获取一些调试输出。如何执行此操作取决于您使用的日志记录框架,但应该是直截了当的。

      【讨论】:

      • 感谢 gid,我使用 配置了 log4j 我看不到任何类似的日志记录“使用名称创建新交易”。 ?
      • 下一站是检查您从上下文返回的 IUserProfileService 实例是否是代理,并且该代理具有对 TransactionInterceptor 的引用,最好在调试器中执行此操作
      猜你喜欢
      • 1970-01-01
      • 2014-03-04
      • 1970-01-01
      • 1970-01-01
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      • 2022-07-05
      • 1970-01-01
      相关资源
      最近更新 更多