【问题标题】:Grails: Declarative TransactionsGrails:声明式事务
【发布时间】:2010-07-28 16:10:40
【问题描述】:
class ExtHotelApiService extends HotelApiService {

  static scope = "singleton"
  static transactional = true

def save(params) {
  params.hotels.each{ht->
   try{
   transactionalSave(ht)
   } catch(Exception e) {
     /* exceptions handling */
   }
}
}

 @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, rollBackFor=RollBackError.class)
  def transactionalSave(ht) throws RollBackError {
 /* saving hotel and hotel description */
}
}

注意几点:

  1. ExtHotelApiService 扩展了 HotelApiService
  2. RollBackError 扩展 RuntimeException
  3. ExtHotelApiService.transactional =
  4. HotelApiService.transactional =
  5. 我们必须保存酒店,然后才保存描述
  6. 如果描述无效(无法持久化),我们必须回滚交易(而不是持久化酒店)

所有代码都是根据Declarative Transactions guide 编写的,但有一个问题——根本没有发生回滚! :(

事务成功提交,即使在抛出 RollBackError 后,酒店也被持久化到数据库中!

我在哪里犯了错误以及如何以正确的方式处理声明性事务?

【问题讨论】:

    标签: spring grails transactions


    【解决方案1】:

    Spring 声明式事务管理的默认行为告诉事务管理器回滚任何未检查的异常,并忽略任何检查的异常。已检查的异常可以声明为触发回滚,但如果默认的@Transactional 设置保持不变,则已检查的异常不会对当前事务产生任何影响。

    有关这方面的 Spring 文档可在 here 获得,相关章节为 10.5.5 和 10.5.6。特别注意以下几点:

    任何 RuntimeException 触发器 回滚和任何检查的异常 没有。

    【讨论】:

    • RollBackError 是 RuntimeException,即使我将 RollBackError.class 作为 rollBackFor 参数传递,它仍然会忽略它。我只是无法理解-在这种情况下我已经检查了异常,但是如果根据文档作为 rollBackFor 参数传递,即使检查的异常也可以触发回滚,但是...在我的情况下不是:(
    • 如果它是一个 RuntimeException,那你为什么要把它包含在你的方法声明中呢? (并不是说这与问题有关,但仍然很好奇。)
    • grails 文档中的另一点。警告:依赖注入是声明式事务工作的唯一方式。如果你使用 new BookService() 等 new 运算符,你将无法获得事务性服务
    • 1.我已经将它包含在方法声明中,因为它最初只是 Throwable(您可以将 Throwable 类作为 rollBackFor 参数传递) 2. 我没有自己创建任何实例 - 我正在使用依赖注入和单例模式
    • 没问题。对不起,我没有更多的帮助。祝你好运。
    猜你喜欢
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多