1

如果我将事务隔离级别设置为 READ_COMMITTED,是否可以设置不同的表隔离级别,例如 READ_UNCOMMITTED?这样做的原因是对表的更改需要立即对其他事务可见。

Transaction: READ_COMMITTED
Table Foo: READ_UNCOMMITTED

例如,JPA 表 id 生成器

     Entity Type      Next Id
----------------------------------
     EMP                100
     DEPT               5

当一个事务获得 Employee 的新 Id 时,将其 Id 增加到 101。这个新 id 必须立即对其他事务可见。否则会导致Id重复。

假设所有事务的隔离级别都是 READ_COMMITTED。如何在提交当前事务之前使对表的更改对其他事务可见?

Mysql、Oracle db、SqlServer 怎么样?

4

1 回答 1

0

这个新的 id 必须立即对其他事务可见。否则会导致Id重复。

使用 READ_UNCOMMITTED 不会解决您的问题。

假设你的事务读取了最新的 id 值,然后尝试使用 id+1。但是在读取最后一个 id 和尝试使用下一个值之间,一些第三个事务使用了该值,然后你仍然得到一个重复的错误。

这称为竞争条件,即使您使用 READ_UNCOMMITTED,也无法通过快速解决它。

此外,在任何数据库中使用 READ_UNCOMMITTED 都是一个坏主意。如果另一个事务由于某种原因被回滚怎么办?您的事务将读取永远不会“存在”的数据,因为它从未提交过。

正是由于这个原因,所有品牌的 RDBMS 都具有在事务范围之外生成 id 值的功能。

这些实现的共同点是数据库可以在某种全局范围内生成新的 id 值,从而保证两个并发事务不会生成相同的值。

您必须使用该机制来生成唯一的 id 值,而不是依赖于SELECT id+1...解决方案。SELECT受事务隔离的约束,因此它无法看到最近生成的 id 值,无论是否已提交。但是数据库知道,它永远不会向两个不同的事务返回相同的值。

不幸的是,每个实现的语法都不同,因此很难编写在所有品牌的 SQL 数据库上都工作相同的 SQL 代码。

于 2018-03-21T00:01:02.057 回答