`
windlike
  • 浏览: 16473 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring的只读事务嵌套

    博客分类:
  • Java
阅读更多
spring的事务有只读与可写之分:
两者的根本区别就是只读事务所做的数据库修改不会提交到数据库.
需要注意2点:
1.HibernateTemplate的如下API检查了当前事务是否只读,如果是只读会抛出InvalidDataAccessApiUsageException异常:
save,update,saveOrUpdate,saveOrUpdateAll,replicate,persist,merge,delete,deleteAll
但是HibernateTemplate并未保证只读事务进行数据库写操作肯定抛出此异常,在只读事务中使用以上API之外的方法做数据库写操作就不会抛出异常,也不会提交到数据库.
2.如果只读事务中嵌套了另一个事务,且内嵌事务的级别设置为PROPAGATION_REQUIRED,则内嵌事务同样是只读的,不会真正提交,即便内层事务为非只读事务.
个人浅见,欢迎讨论.
分享到:
评论
1 楼 dizdev 2009-06-12  
我的观点

spring 本身不存在事务。 所谓spring事务只是一个非常透明的帮助类来处理一些初级程序员没有能力处理的工作,这样可以极大的掩盖程序的复杂性。其实spring tx是整个spring framework中最简单的module.

Readonly事务的特性是

事务资源不做任何事情,这样在一个有事务context的thread中,Readonly事务可以大大的优化事务,不需要去执行和监视 transaction对象的 Prepare(),commit(),abort()的回调函数。 更深层次的考虑是

1:在XA下,所有Read-Only的事务将直接转变为 1 阶段事务。
2:整个事务不会去Lock事务资源。事务资源可以自由释放,并且被其他thread引用。(这个是并发控制中,事务资源优化的主要手段)

所以楼主提到的HBTemplate的问题就会也能显然,由于spring tx 在特定情况下将一个tx设置为Read-Only,那么就不会触发commit的回调。因此,不会有任何异常抛出。

至于2:
在我的理解中,嵌套事务就是2个互不干扰的local tx进行一前一后的事务绑定。楼主所说的问题应该是spring使用了DefaultTransactionStatus这个类,而这个类的特性是在适当的时候将tx设置为Ready-Only来达到优化tx资源的目的。

以上是个人观点,欢迎讨论

相关推荐

Global site tag (gtag.js) - Google Analytics