不同DAO中的Spring事务无论如何都不起作用?

时间:2009-10-28 07:23:15

标签: java mysql spring hibernate transactions

以下是我在摘要中的实施

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

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)我的Transation Manager配置/数据源如下:

<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();
        }

2 个答案:

答案 0 :(得分:1)

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

  

MySQL Server(版本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所提到的那样,不是对交易的要求。

答案 1 :(得分:1)

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

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

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

假设这是真的,接下来要做的是从org.springframework.transaction.support.AbstractPlatformTransactionManager获取一些调试输出。如何做到这一点取决于您使用的是哪种日志框架,但它应该是直截了当的。