我将grails 1.3.7与Oracle 11g一起使用并尝试管理内部事务。 我有一个bean Person被传递给事务性的(Propagation.REQUIRED)服务方法,他做了一些修改。然后将它传递给另一个事务性(propagation = Propagation.REQUIRES_NEW)方法,该方法进行一些其他修改然后抛出异常。 我期望看到的是第二次服务的所有修改的回滚,但仍然有效的第一次服务。情况就是这样:
//outer transaction
class MyService {
def nestedService
@Transactional(propagation = Propagation.REQUIRED)
public void testRequiredWithError(Person person) {
person.name = 'Mark'
try {
nestedService.testRequiresNewWithError(person)
} catch (RuntimeException e) {
println person.age //this prints 15
println e
}
}
}//end MyService
//inner transaction
class NestedService{
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void testRequiresNewWithError(Person person) {
person.age = 15 //expected after Exception will be discarded
throw new RuntimeException("Rollback this transaction!")
}
}
然后我运行grails控制台并在结束后检查数据库。 ...
def p = Person.get(671)
def myService = ctx.myService
println p.name //'John'...from DB
println p.age //25...from DB
myService .testRequiredWithError(p)
println p.name // 'Mark'....correct
println p.age // 15....UNEXPECTED..
//same result checking on the DB after console ends and transaction flushes
我试图在transactionManager.setNestedTransactionAllowed(true)
的引导程序中激活后使用Propagation.NESTED,并使用此帖子中的保存点
grails transaction set savepoint
但结果仍然相同。
我错过了什么????
提前谢谢。
答案 0 :(得分:1)
我参加派对有点晚了,但如果你找不到答案,我想我知道你为什么会遇到交易问题。
我查看了有关保存点问题的讨论的链接。根据该讨论,您使用MySQL作为数据源。默认情况下,MySQL不支持事务,为了实现这一点,您需要以特殊方式创建表。我在下面提供了一个链接,解释了当您想要使用事务时如何在MySQL中创建表:
http://www.tutorialspoint.com/mysql/mysql-transactions.htm
编辑:本文建议将表的类型设置为InnoDB以支持事务。以下是一个示例:
mysql> create table tcount_tbl
-> (
-> tutorial_author varchar(40) NOT NULL,
-> tutorial_count INT
-> ) TYPE=InnoDB;
值得注意的是,这不是支持交易的唯一类型,但却是最常见的类型。 MySQL 5.5及更高版本应该自动创建表格类型为InnoDB。
希望这有帮助!
答案 1 :(得分:0)
我测试p.isAttached()
因为事务回滚将域对象从Hibernate会话中分离出来。同样在测试中,我将从数据库重新加载域对象 - 再次有效p = Person.get(671)
以从数据库重新加载数据。
我认为测试后age
属性设置为15的原因是在域对象和数据库不同步之后(并且域对象被分离)。
有关详情,请参阅:https://weblogs.java.net/blog/blog/davidvc/archive2007/04/jpa_and_rollbac.html