无法获取Spring事务回滚(java + mysql)

时间:2011-06-20 22:50:29

标签: java mysql spring transactions

上周我终于让我的应用程序使用了交易。我正在使用Spring声明式事务,并且我知道事务本身正在工作,因为它在一次事务中使用数千个插入的内容从5-10分钟到5-10秒。数据库是MySQL,所有表都是InnoDB。所以我想让这个函数回滚,如果它不起作用。基本上,它是导入xml文件并从xml构建数据库表。因此,如果某些内容失败,我不希望部分上传或者它会不一致。我一直在关注Spring文档,因为我确实得到了运行的事务,所以我猜测一般配置是正确的。

以下是.xml文件的相关部分:

<tx:advice id="txAdvice" transaction-manager="txManager">
  <tx:attributes>
    <tx:method name="get*" read-only="true"/>
    <tx:method name="uploadModelToProject" rollback-for="Throwable"/>
    <tx:method name="*"/>
  </tx:attributes>
</tx:advice>

        

以下是该服务的相关部分:

public interface ModelService {
    // interface to upload an LSI XML file of the  model into a project
    public Model uploadModelToProject(Project proj, String xmlFile);
}

uploadModelToProject调用SAX Parser实现中的方法,然后实现解析

public Model importModelToProject(Project proj, String xmlInputFileName) throws SAXException, IOException, ParserConfigurationException, ImportException {

    //get a factory
    SAXParserFactory spf = SAXParserFactory.newInstance();
    try {

        //get a new instance of parser 
        SAXParser sp = spf.newSAXParser();          

        //parse the file and also register this object for callbacks
        sp.parse(xmlInputFileName, this);                               

    } finally {
        newModel = null;
    }

    return newModel;

}

我尝试过使用rollback-for =“Throwable”,rollback-for =“Exception”,rollback-for =“ImportException”(我自己的例外)。然后我在代码中手动抛出异常并且它没有工作。我不知道我是否需要一些传播参数或其他一些设置。似乎我没有遗漏任何明显的东西。有人有什么建议吗?发生的一切都是抛出异常,一切都进入数据库。我错过了一个明显的步骤吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

我没有得到任何建议的啃,但我终于想出来了所以我想我会发布答案以防其他人试图找出回滚的东西。我打开了commons / log4j日志记录的调试级别,这样我就可以看到Spring框架中发生了什么。丰富的输出,但很有用。

原来我缺少的是了解Spring Framework拦截和捕获配置中的异常的位置,以便启动回滚。

我的第一组代码,在我处理事务之前,我正在从XML解析中捕获异常并且只返回一个空指针供调用者处理。我没有想到Spring会处理异常的位置,所以如果我抓住异常并且不重新抛出它就不会打击我,那么Spring就不知道了。我的下一次尝试是传递所有异常,但没有在任何地方处理它,错误地认为Spring是神奇的。好消息是交易被回滚,坏消息是错误的页面被返回给用户。

所以我的“啊哈!”当我意识到配置中指定的方法(即服务中的方法)必须是抛出异常的那个时刻。是的,在意识到这一点之后,这似乎是显而易见的,但我花了很多时间来解决这个问题。所以在我的例子中,“uploadModelToProject”方法需要在获得异常之后重新抛出异常,并且服务中该方法的调用者需要处理异常,这恰好在Spring截获并执行回滚之后发生。

此外,我没有在我的XML Importer中使用我的低级函数抛出所有这些不同类型的异常,而是创建了我自己的“ImportException”,捕获了异常,并向上抛出了ImportException。

希望这有助于某人!