Spring中的@Transactional深度分析之二

5. @Transactional之isolation 隔离级别所要解决的问题是在应用程序中,存在多个事务同时在运行之时,需要解决和处理好的问题。那首先来看看,一般会出现哪些问题呢?先来看看吧。 脏读(dirty read) 一个事物更新了数据库中的某些数据,另一个事物读取了这些数据,这时前一个事物由于某些原因回滚了,那么第二个事物读取的数据就是“脏数据” 不可重复读(non-repeatable read) 一个事物需要两次查询同一数据,但两次查询中间可能有另外一个事物更改了这个数据,导致前一个事物两次读出的数据不一致。 幻读 (phantom read) 一个事物两次查询同一个表,但两次查询中间可能有另外一个事物又向这个表中插入了一些新数据,导致前一个事物的两次查询不一致 下面来看看Spring中@Transactional中Isolation有具备的值:

其与事务中容易出现的问题对应关系具体如下:

具体如何来设置具体的隔离界别,则依据业务系统具体可以容忍的程度而定。Serializable最为严格,,然而效率最低;Read Uncommited效率最高,但是容易出现各种问题,中间的2个级别介于二者之间,故本质上是效率与出错概率的平衡与妥协。

6. @Transactional之timeout

用于设置事务处理的时间长度,阻止可能出现的长时间的阻塞系统或者占用系统资源。单位为秒。如果超时设置事务回滚,并抛出TransactionTimedOutException异常。

Spring事务超时 = 事务开始时到最后一个Statement创建时时间 + 最后一个Statement的执行时超时时间(即其queryTimeout)。

关于事务超时时间的计算可以参考:

7. @Transactional之readOnly

默认情况下是false,可以显示指定为true, 告诉程序该方法下使用的是只读操作,如果进行其他非读操作,则会跑出异常;这个紧紧适用于只有readOnly标识的情况下,当其与propagation机制同时使用之时,则会出现只读设置被覆盖的情况,比如在required的情况下。在使用 REQUIRED 传播模式时,会抛出一个只读连接异常。使用 JDBC 时是这样。使用基于 ORM 的框架时,只读标志只是对数据库的一个提示,并且一条基于 ORM 框架的指令(本例中是 Hibernate)将对象缓存的 flush 模式设置为 NEVER,表示在这个工作单元中,该对象缓存不应与数据库同步。不过,REQUIRED 传播模式会覆盖所有这些内容,允许事务启动并工作,就好像没有设置只读标志一样。

具体的详细内容可以参考:

8. @Transactional之rollbackForClassName/rollbackFor

Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked,如果遇到checked意外就不回滚。

用来指明回滚的条件是哪些异常类或者异常类名。用法比较简单,这些不再赘述。

9. @Transactional之noRollbackForClassName/noRollbackFor 作用雷同于8, 用来指明在抛出特定异常的情况下,不进行数据库的事务回滚操作。

10. 总结

在针对@Transactional的各个属性进行详细分析之后,相信各位对他们具体的含义和应用场景有了一定的认识,使用起来便会不再那么迷茫和犹豫;非常感谢Spring给我们提供了这些便捷的事务管理方式,摆脱了繁琐的体力活,提升了开发的效率。

在这里这些资料的过程中,参考诸多blog的文字,不再一一列出,一并致谢,更多的是希望站在这些巨人的肩上,能把技术点和应用点,解释清楚即可。

我想去旅行,一个人背包,一个人旅行,

Spring中的@Transactional深度分析之二

相关文章:

你感兴趣的文章:

标签云: