Spring事务readOnly和隔离级别

时间:2018-02-22 12:17:33

标签: java spring hibernate transactions

我读到了spring / hibernate中的传播和隔离。 我有一个特定的方法,我们有

0. @Transactional (the default spring annotation)
1. read several rows
2. some business logic
3. read (from other table using some data from the first read)

这对我来说有点不安全。如果其他人在第2步中删除了一行,该怎么办? 我认为我应该将方法注释更改为

@Transactional(readOnly = true, isolation = Isolation.SERIALIZABLE)

这是我的具体案例的有效解决方案吗? (任务是修复事务注释,导致系统出现一些问题,并尽可能少地改变其他代码行) 提前谢谢。

2 个答案:

答案 0 :(得分:1)

如果我理解你的情况,你有一些方法,可以从数据库中读取几个。

因此,如果您的方法只是从数据库中读取,那么您只需要注释:@Transactional(readOnly = true, isolation = Isolation.SERIALIZABLE)

因为事实上你只是从数据库中读取。

但是,如果您的方法同时提供对数据库读取和读取的访问权限。写 - 最好的方法是将它分成两个方法,其中一个方法是readOnly。

答案 1 :(得分:1)

它取决于您所说的不安全,您所编写的业务逻辑,在您的示例中您只执行读取操作,而在快速读/写操作中建议使用serializable,在您的情况下,如果在第一个表中更新某些内容可序列化的事务将在没有执行任何操作的情况下运行 - 如冻结环境, 只要其他事务插入数据,它就会对您不可见,因此最后您的第二次读取结​​果可能是错误的

正如他们在oracle上提到的那样:

  

除非对此类应用程序级别的一致性检查进行编码,否则可能会导致数据库不一致,即使在使用可序列化事务时也是如此。

此外,当您在此处使用serializable时,您必须知道在您尝试更新同一个表时,代码(其他类)中可能出现的无法序列化访问异常,这可能很棘手

解决这个问题的另一种方法是使用Read Committed Isolation,当你重新实现第二次读取时记住表示数据库的真实状态,我的意思是如果其他行接收更新并且提交它们必须考虑使用第一次阅读时使用的数据,如果没有您方法的真实示例,我无法为您提供完整的工作示例。