事务隔离级别:设置表隔离级别不同

时间:2018-03-20 20:36:14

标签: sql database jpa transaction-isolation id-generation

如果我将事务隔离级别设置为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怎么样?

1 个答案:

答案 0 :(得分:0)

  

此新ID必须立即对其他交易可见。否则会导致重复的Id。

使用READ_UNCOMMITTED无法解决您的问题。

假设您的事务读取了最新的id值,然后尝试使用id + 1。但是在读取最后一个id并尝试使用下一个值的时刻之间,某个第三个事务使用了该值,然后您仍然遇到重复错误。

这称为race condition,即使您使用READ_UNCOMMITTED,也无法通过快速解决它。

此外,在任何数据库中使用READ_UNCOMMITTED都是一个坏主意。如果由于某种原因回滚其他交易怎么办?您的交易将具有永远不会“存在”的数据,从未提交过。

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

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

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

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