读了 IBM developerWorks 上的文章:“事务策略: 了解事务陷阱 ”,总结一下。
- 在使用 Spring 的事务注释的时候,还要在配置文件中加入
<tx:annotation-driven transaction-manager="transactionManager"/>
使用过 Spring 的事务注释的应该都知道这一条。 - 只读操作不用设置事务。我怎么记得只读也是需要设置事务的,这是为了保证读操作不会其它事务中间状态的数据。对于某些领域的应用,比如金融,这一条是很重要的。当然,如果这一点并不重要,对于读操作不设置事务,是可以提高性能的。
- 如果没有事务,使用 ORM 执行的写操作通常是不会执行的,除非你执行 flush 操作。
- 要注意,不要随便使用 REQUIRES_NEW。在使用 REQUIRES_NEW 事务属性时,如果存在现有事务上下文,当前的事务会被挂起并启动一个新事务。方法结束后,新的事务被提交,原来的事务继续执行。通常情况使用 REQUIRES 就行了,但文中也介绍了一个需要使用 REQUIRES_NEW 场景。总结一下,就是当某个操作与其调用操作相对独立的时候,即这个操作成功与否并不取决于其父操作是否成功,这个时候就要考虑使用 REQUIRES_NEW 了。
- 对于 Spring 和 EJB3 的事务注释,默认情况下,只有 Runtime Exception 发生时才会回滚事务。所以,下面这段代码是不会有事务回滚的。
Spring 可以通过@Transactional(propagation=Propagation.REQUIRED) public TradeData placeTrade(TradeData trade) throws Exception { try { insertTrade(trade); updateAcct(trade); return trade; } catch (Exception up) { //log the error throw aCheckedException; } }
@Transactional
注释中的rollbackFor
参数进行改变默认规则;EJB3 需要用 EntityManager 的 setRollbackOnly() 方法。