2014-10-28 55 views
1

我知道这个问题已被问过很多次,但我找不到任何问题的答案。@transactional,wildfly,mysql(innodb)ejb not rolling back

我有一个使用wildfly 8作为容器的Web应用程序。 问题是,如果我在我的ejb中抛出一个异常,事务不会回滚。

我知道如果我用@stateless和@localbean注释我的ejb,它是默认的事务。

我曾尝试以下的事情:

  • 检查,如果,如果我在工作台在MySQL编写SQL代码

    begin; 
    INSERT INTO `bookservicewebapp`.`author` (`firstname`, `lastname`) VALUES ('firstname1', 'lastname1'); 
    SELECT * FROM bookservicewebapp.author; 
    INSERT INTO `bookservicewebapp`.`author` (`firstname`, `lastname`) VALUES ('firstname2', 'lastname2'); 
    rollback; //worked! 
    
  • 关闭自动提交的数据库并回滚事务// in my.ini

  • 检查是否使用了innodb
  • 使用注释该方法自己
  • 掷扩展运行时异常,并标注有@ApplicationException(rollback=true)
  • 例外有没有例外,在所有
  • 我试图挑起暂停时以@TransactionTimeout(unit=TimeUnit.SECONDS,value=5)和方法内等待6秒逮住。

代码正在讨论的是:

public List<Long> saveBooks(List<Book> books){ 
     List<Long> savedBooksIds = new ArrayList<>(books.size()); 
     for (Book book : books) { 
      // are these authors in the db? 
      List<Author> fetchedAuthors = new ArrayList<Author>(); 
      if (book.getAuthors() == null || book.getAuthors().size() == 0) { 
       throw new RuntimeException("no authors"); 
      } 

      for (Author a : book.getAuthors()) { 
       //select all authors with given attributes 
       List<Author> buf = getAuthorsByStuff(a.getFirstname(), 
         a.getLastname(), a.getBirthday()); 
       if (buf.size() != 1) { 
        throw new RollbackException("author " + a.getFirstname() 
          + " does not exist"); 
       } else { 
        fetchedAuthors.add(buf.get(0)); 
       } 
      } 
      book.setAuthors(fetchedAuthors); 
      // is the publisher in the db? 
      if (book.getPublisher() != null) { 
       Publisher pub = book.getPublisher(); 
       //select all publishers with given attributes 
       List<Publisher> buf = getPublishersByStuff(pub.getName(), 
         pub.getPostcode(), pub.getCountrycode()); 
       if (buf.size() != 1) { 
        throw new RollbackException("publisher " + pub.getName() 
          + " does not exist"); 
       } else { 
        book.setPublisher(buf.get(0)); 
       } 
      } 
      //em.persist(book); 
      savedBooksIds.add(em.merge(book).getId()); 
     } 
     return savedBooksIds; 
    } 

选择代码:

public List<Author> getAuthorsByStuff(String firstname, String lastname, 
      Date date) { 
     return em.createNamedQuery("Author.getAuthorsByStuff", Author.class) 
       .setParameter("firstname", firstname) 
       .setParameter("lastname", lastname) 
       .setParameter("birthday", date).getResultList(); 
    } 

回答

2

错误是wildfly是配置错误。 必须启用JTA并且必须配置隔离级别。

 <datasource jta="true" jndi-name="java:jboss/datasources/BookServiceWebAppDS" pool-name="BookServiceWebAppDS" enabled="true" use-ccm="false"> 
     <connection-url>jdbc:mysql://localhost:3306/bookservicewebapp</connection-url> 
     <driver-class>com.mysql.jdbc.Driver</driver-class> 
     <driver>mysql</driver> 
     <transaction-isolation>TRANSACTION_REPEATABLE_READ</transaction-isolation> 
     <security> 
      <user-name>username</user-name> 
      <password>password</password> 
     </security> 
     <validation> 
      <validate-on-match>false</validate-on-match> 
      <background-validation>false</background-validation> 
     </validation> 
     <statement> 
      <share-prepared-statements>false</share-prepared-statements> 
     </statement> 
    </datasource>