我知道这个问题之前已被问过很多次,但我找不到任何问题的答案。
我有一个使用 Wildfly 8 作为容器的 Web 应用程序。 问题是,如果我在 ejb 中抛出异常,事务不会回滚。
我知道如果我用 @stateless 和 @localbean 注释我的 ejb,它就是默认的事务性的。
我尝试过以下操作:
如果我在工作台中编写 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!
在 my.ini 中关闭 mysql 中的自动提交
- 检查是否使用了 innodb
- 我自己用
@Transactional(rollbackOn = Exception.class)
注释该方法 - 抛出一个扩展运行时异常的异常,并用
@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();
}
最佳答案
错误是 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>
关于mysql - @transactional、wildfly、mysql(innodb) ejb 不回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26607078/