快速业务通道

事务策略: 了解事务陷阱-在Java平台中实现事务时要注意的常见错误 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-14

@Transactional 只读标志陷阱

我在工作中经常碰到的一个常见陷阱是 Spring @Transactional 注释中的只读标志没有得到恰当使用 。这里有一个快速测试方法:在使用标准 JDBC 代码获得 Java 持久性时,如果只读标志设置为 true, 传播模式设置为 SUPPORTS,清单 5 中的 @Transactional 注释的作用是什么呢?

清单 5. 将只读标志与 SUPPORTS 传播模式结合使用 — JDBC

@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)
public long insertTrade(TradeData trade) throws Exception {
  //JDBC Code...
}

当执行清单 5 中的 insertTrade() 方法时,猜一猜会得到下面哪一种结果:

抛出一个只读连接异常

正确插入交易订单并提交数据

什么也不做,因为传播级别被设置为 SUPPORTS

是哪一个呢?正确答案是 B。交易订单会被正确地插入到数据库中,即使只读标志被设置为 true,且 事务传播模式被设置为 SUPPORTS。但这是如何做到的呢?由于传播模式被设置为 SUPPORTS,所以不会启 动任何事物,因此该方法有效地利用了一个本地(数据库)事务。只读标志只在事务启动时应用。在本例 中,因为没有启动任何事务,所以只读标志被忽略。

如果是这样的话,清单 6 中的 @Transactional 注释在设置了只读标志且传播模式被设置为 REQUIRED 时,它的作用是什么呢?

清单 6. 将只读标志与 REQUIRED 传播模式结合使用 — JDBC

@Transactional(readOnly = true, propagation=Propagation.REQUIRED)
public long insertTrade(TradeData trade) throws Exception {
  //JDBC code...
}

事务策略: 了解事务陷阱-在Java平台中实现事务时要注意的常见错误(5)

时间:2011-10-21 IBM Mark Richards

执行清单 6 中的 insertTrade() 方法会得到下面哪一种结果呢:

抛出一个只读连接异常

正确插入交易订单并提交数据

什么也不做,因为只读标志被设置为 true

根据前面的解释,这个问题应该很好回答。正确的答案是 A。会抛出一个异常,表示您正在试图对一 个只读连接执行更新。因为启动了一个事务(REQUIRED),所以连接被设置为只读。毫无疑问,在试图执 行 SQL 语句时,您会得到一个异常,告诉您该连接是一个只读连接。

关于只读标志很奇怪的一点是:要使用它,必须启动一个事务。如果只是读取数据,需要事务吗?答 案是根本不需要。启动一个事务来执行只读操作会增加处理线程的开销,并会导致数据库发生共享读取锁 定(具体取决于使用的数据库类型和设置的隔离级别)。总的来说,在获取基于 JDBC 的 Java 持久性时 ,使用只读标志有点毫无意义,并会启动不必要的事务而增加额外的开销。

使用基于 ORM 的框架会怎样呢?按照上面的测试,如果在结合使用 JPA 和 Hibernate 时调用 insertTrade() 方法,清单 7 中的 @Transactional 注释会得到什么结果?

清单 7. 将只读标志与 REQUIRED 传播模式结合使用 — JPA

@Transactional(readOnly = true, propagation=Propagation.REQUIRED)
public long insertTrade(TradeData trade) throws Exception {
  em.persist(trade);
  return trade.getTradeId();
}

清单 7 中的 insertTrade() 方法会得到下面哪一种结果:

抛出一个只读连接异常

正确插入交易订单并提交数据

什么也不做,因为 readOnly 标志被设置为 true

正确的答案是 B。交易订单会被准确无误地插入数据库中。请注意,上一示例表明,在使用 REQUIRED 传播模式时,会抛出一个只读连接异常。使用 JDBC 时是这样。使用基于 ORM 的框架时,只读标志只是 对数据库的一个提示,并且一条基于 ORM 框架的指令(本例中是 Hibernate)将对象缓存的 flush 模式 设置为 NEVER,

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号