【问题标题】:Hibernate 4 + Spring 3.2 + Transaction Manager + No Roll Back in MysqlHibernate 4 + Spring 3.2 + 事务管理器 + Mysql 中不回滚
【发布时间】:2013-07-22 04:49:16
【问题描述】:

我需要一些帮助。我在使用休眠和弹簧的事务时遇到问题。 我正在尝试填写 mysql 中的文件表。我的第一个插入效果很好,第二个不起作用(但这是正常的......)。但是第一个插入的数据仍然存在于表中。这不符合交易的概念。我可以吗?

我认为第二次尝试在数据库中插入损坏的数据时应该执行回滚(损坏的数据是指与字段约束不匹配的数据) 我的第一次插入没问题,但由于第二次插入“损坏”,所以第一次插入应该回滚,并且表中不应该存在任何数据。 或者事实并非如此。第一个数据,来自第一个插入仍然在表中。它不应该仍然存在吗?

我试图查看已检查/未检查的异常内容,@transactionnal 配置错误但没有成功...

如果你有任何想法......

谢谢!!

Main.java:

    public static void main( String[] args ) throws Exception{

            ApplicationContext appContext = new ClassPathXmlApplicationContext(    "classpath:webConfiguration/applicationContext.xml");

            FileBo aFileBo = (FileBo) appContext.getBean("fileBo");
// Data are ok, there is an insert.
File aFile = File (6778687,".bam");             
aFileBo.save(aFile);

// Error is produce here because the ".pdf" value is not tolerated in the enum field we want to fill up. No data is inserted. But a rollback should be done and data inserted before should be erased ?
File anAnotherFile = File (6567887,".pdf");             
aFileBo.save(anAnotherFile);

}

FileBoImpl.java

public class FileBoImpl implements FileBo{
FileDao fileDao;


public FileDao getFileDao() {
    return fileDao;
}


public void setFileDao(FileDao fileDao) {
    this.fileDao = fileDao;
}

@Transactional// one transaction for multiple operations
public void save(com.clb.genomic.lyon.model.File aFile) {

 fileDao.save(aFile);
}

休眠.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd " >

<!-- Hibernate session factory -->
<bean id="sessionFactory"  class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

<property name="dataSource">
  <ref bean="dataSource"/>
</property>

<property name="hibernateProperties">
   <props>
     <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
     <prop key="hibernate.show_sql">true</prop>
   </props>
 </property>

 <property name="mappingResources">
   ...
  </property>

</bean>

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

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

</bean> 

在 applicationContext.xml 中调用的 Beans.xml 也带有 Hibernate.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">


<!--  Data Access Object -->

<bean id="fileDao" class="com.clb.genomic.lyon.dao.FileDaoImpl" >
    <property name="sessionFactory" ref="sessionFactory"></property>
</bean> 

<!--  Business Object  -->

<bean id="fileBo" class="com.clb.genomic.lyon.bo.FileBoImpl" >
    <property name="fileDao" ref="fileDao"></property>
</bean> 

</beans>

【问题讨论】:

    标签: mysql spring rollback spring-transactions hibernate-4.x


    【解决方案1】:

    您在这里使用了两个单独的事务:一个用于保存第一个文件,另一个用于保存第二个文件。因此,当第二个回滚时,第一个已经提交。

    如果您希望两个保存成为同一个事务的一部分,那么您应该从 main 调用单个事务方法,并从该方法保存两个文件:

    public static void main( String[] args ) throws Exception{
        ApplicationContext appContext = new ClassPathXmlApplicationContext(    "classpath:webConfiguration/applicationContext.xml");
    
        FileBo aFileBo = (FileBo) appContext.getBean("fileBo");
        // Data are ok, there is an insert.
        File aFile = File (6778687,".bam");    
        File anAnotherFile = File (6567887,".pdf");  
    
        aFileBo.save(aFile, anotherFile);
    }
    
    public class FileBoImpl implements FileBo {
        FileDao fileDao;
        // ...
    
        @Transactional
        public void save(com.clb.genomic.lyon.model.File aFile, 
                         com.clb.genomic.lyon.model.File bFile) {
    
            fileDao.save(aFile);
            fileDao.save(bFile);
    
        }
    }
    

    【讨论】:

    • 好的,这对我来说很清楚 :-) 所以这让我想知道您如何处理要在同一事务中保存的多个实体。在我的代码中,所有 DaoEntite 都有一个对应的 BoEntiti(如我之前所示)。当实体具有关系(多对多、一对多等)时,它们是否都集成在同一个事务中?想象一下,您有类似这样的 Repertory -> File(一对多关系)和 File -> File_Rights -> Rights(多对多关系)如果我执行 repertoryBo.save()、fileBo.save () 和 rightsBo.save() ,是不是因为关系而发生在同一笔交易中?
    • 在使用 Transactional 注释的方法调用中所做的一切都是单个事务的一部分。它(几乎)就这么简单。服务层(您称之为 BO)的作用是提供与必须在单个事务中完成的事情相对应的事务方法。如果您的服务层只有 save() 方法,它不会向 DAO 层添加任何内容。它应该有像 transferAmount() 这样的方法来检查输入,从帐户中删除金额,将金额添加到另一个帐户并保存审计日志,所有这些都在单个事务中。
    • 我仍然迷失在当你有 3 张桌子时,所以 3 pojos class,3 daos 的想法。您希望在全局事务中保存 3 个表的数据。因此,您不会设计 3 个 BO(服务)类,并使用 Transactionnal 注释的保存方法。我是否需要使用 transactionnal 方法实现 1 个服务类来保存所有这些。或者我是否必须在映射和关系模式中使用级联参数设置为“保存更新或全部”以使 3 个服务在同一个事务中一起工作(在这种情况下,将有 3 个保存方法注释事务)?你看到了什么我试着理解?谢谢 :)
    猜你喜欢
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    • 2016-07-25
    • 2011-07-11
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多