2013-07-23 63 views
0

我需要一些帮助。我在使用hibernate和spring进行事务时遇到问题。 我想填充MySQL中的文件表。我的第一张插入效果很好,第二张插入不起作用(但这很正常......)。但是第一个插入的数据仍然存在于表格中。这不符合交易的概念。我没事吧?Hibernate 4 + Spring 3.2 +事务管理器+在Mysql中不回滚

我觉得回滚应执行我第二次尝试在数据库中插入损坏的数据(由损坏的数据,我的意思是不匹配字段约束数据) 我第一次插入是确定的,但作为第二插入是“损坏”的第一个插入应该是回滚的,并且表中没有数据。 或者事实并非如此。来自第一次插入的第一个数据仍然在表格中。它不应该仍然存在?

我想看看检查/ uncheked例外的东西,的@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); 
} 

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 " > 

<!-- 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> 

beans.xml中称为applicationContext.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> 

回答

0

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

如果你希望两个保存到同一个事务的一部分,那么你应该调用从主一个单一的交易方法,并且这两个文件从这个方法保存:

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

    } 
} 
+0

确定这显然对我来说: - )所以这让我想知道你如何处理你想要保存在同一个事务中的多个实体。在我的代码中,所有DaoEntite都有相应的BoEntitie(正如我之前展示的)。当实体有关系(多对多,一对多等)时,它们是否都集成在同一个事务中?假设你有类似这样的Repertory - > File(一对多关系)和File - > File_Rights - > Rights(多对多关系)如果我做repertoryBo.save(),fileBo.save()和rightsBo.save() ,它是否发生在同一个交易中,因为这种关系? – ZheFrench

+0

在用Transactional注释的方法的调用内完成的所有事情都是单个事务的一部分。它(几乎)如此简单。服务层(您称之为BOs)的作用是提供事务性方法,这些方法必须与单个事务中必须完成的事情相对应。如果你的服务层只有save()方法,它不会向DAO层添加任何东西。它应该具有的方法是transferAmount(),它可以检查输入,从账户中删除金额,将金额添加到另一个账户并保存审计日志,全部在一个事务中进行。 –

+0

我仍然迷失在这样的想法,即当你有3桌,所以3 pojos类,3道数。您希望在全局事务中保存3个表的数据。所以你不会用Transactionnal注解的save方法设计3个BO(Services)类。我是否需要用方法transactionnal来实现1个Service类来保存所有这些。或者我必须使用级联参数集来映射和关系模式中的“save-update或all”,以使3个服务在同一个事务中一起工作(在这种情况下,会有3个save方法标记为transactionnal)?我试着理解?谢谢:) – ZheFrench