美文网首页
Spring 声明式事务(三)——其余属性

Spring 声明式事务(三)——其余属性

作者: 莫那一鲁道 | 来源:发表于2018-05-14 02:32 被阅读69次

    前言

    众所周知,Spring 的事务属性众多,楼主今天将对 Spring 最常用的事务 —— 声明式事务,进行彻底的解释,包括楼主也写了很多的测试例子。代码地址: 使用 tk-mybatis 的 demo 测试了 Spring 的事务

    readOnly 属性

    该属性的文档中说道:这不是一个百分百限制读操作之外的属性。

    什么意思呢?虽然从字面意思看,是只读,但具体看数据库的实现。

    mysql 数据库中,如果设置了这个属性,那么驱动将返回一个异常。
    oracle 和 sqlServer 则不会,他们会忽略错误。

    因此,在不同的数据库下使用要注意这点。

    timeout

    该属性单位是秒,不是毫秒。

    从字面上看,是定义这个事务的超时时间。

    我们会想当然的认为这是从事务的方法开始到方法的结束。

    但,不是这样的。

    是从事务方法的开始,到 SQL 语句执行的结束,因此,SQL 语句后面的代码执行时间都不算在 timeout 中的。

    这点非常重要。

    这样将导致下面的代码可能无法达到你想要的结果:

    @Transactional(timeout = 3)
    public void timeOut() {
      userInfoMapper
          .insert(new UserInfo().setUsername("timeout").setPassword("timeout"));
        Thread.sleep(3100);
    }
    

    代码中,我们想让这个事务耗时超过 3 秒,那么就可以触发 timeout ,让 insert 无法提交。然而这时不可能的。因为,我们刚刚说,Sql 执行结束后,超时的计时就结束了。

    而下面的例子则可以正确的触发 timeout:

    @Transactional(timeout = 3)
    public void timeOut() {
      Thread.sleep(3100);
      userInfoMapper
          .insert(new UserInfo().setUsername("timeout").setPassword("timeout"));
    }
    

    代码中,从事务的开始到 sql 执行结束的总时间超过了 timeout 设定的时间。成功触发 timeout 机制 —— 抛出异常。

    rollbackFor 和 noRollbackFor

    定义一个 Class 数组,需要继承自 Throwable,也就是异常。

    事务需要回滚,那么什么样的异常才能让事务回滚?

    默认是 RuntimeException 和 Error。代码如下:

    用户可以自定义回滚类似和反回滚类型。

    上面的两个属性是相反的。

    rollbackForClassName 和 noRollbackForClassName

    这两个其实和上面的是一样的功能,只是这里使用了字符串,在某些类加载器不同的场合,也许有用武之地。注意,这里只需要写简单类名即可,无需写全类名。

    相关文章

      网友评论

          本文标题:Spring 声明式事务(三)——其余属性

          本文链接:https://www.haomeiwen.com/subject/ogordftx.html