事务隔离级别:设置 table 不同的隔离级别
transaction isolation level: set table isolation level differently
如果我将事务隔离级别设置为 READ_COMMITTED,我是否可以设置不同的 table 隔离级别,例如 READ_UNCOMMITTED?这样做的原因是
对 table 的更改需要立即对其他交易可见。
Transaction: READ_COMMITTED
Table Foo: READ_UNCOMMITTED
例如,JPA table id 生成器
Entity Type Next Id
----------------------------------
EMP 100
DEPT 5
当一笔交易获得新的Employee Id时,将其Id增加到101。这个新的
id 必须立即对其他事务可见。否则会造成重复的Id。
假设所有事务的隔离级别都是READ_COMMITTED。
如何在提交当前事务之前使对 table 的更改对其他事务可见?
Mysql、Oracle 数据库、SqlServer 怎么样?
This new id must be visible to other transactions immediately. Otherwise it will cause duplicate Id.
使用READ_UNCOMMITTED 不会解决您的问题。
假设你的事务读取了最新的id值,然后尝试使用id+1。但是在读取最后一个 id 和尝试使用下一个值之间,一些第三个事务使用了那个值,然后你仍然有一个重复的错误。
这叫一个race condition,就算用READ_UNCOMMITTED也不能速战速决
此外,在任何数据库中使用 READ_UNCOMMITTED 都是一个坏主意。如果其他事务由于某种原因被回滚怎么办?您的事务将读取永远不会 "exist" 的数据,因为它从未提交过。
正是由于这个原因,所有品牌的 RDBMS 都具有在事务范围 之外生成 id 值的功能。
- MySQL: AUTO_INCREMENT
- 甲骨文:SEQUENCE
- 微软SQL服务器:IDENTITY
这些实现的共同点是数据库可以在一种全局范围内生成新的id值,从而保证两个并发事务不会生成相同的值。
您必须使用该机制来生成唯一的 id 值,而不是依赖于 SELECT id+1...
解决方案。 SELECT
受事务隔离影响,因此它看不到最近生成的 id 值,无论是否已提交。但是数据库知道,它永远不会 return 两个不同事务的相同值。
不幸的是,每个实现的语法都不同,因此很难编写出在所有品牌的 SQL 数据库上都能正常工作的 SQL 代码。
如果我将事务隔离级别设置为 READ_COMMITTED,我是否可以设置不同的 table 隔离级别,例如 READ_UNCOMMITTED?这样做的原因是 对 table 的更改需要立即对其他交易可见。
Transaction: READ_COMMITTED
Table Foo: READ_UNCOMMITTED
例如,JPA table id 生成器
Entity Type Next Id
----------------------------------
EMP 100
DEPT 5
当一笔交易获得新的Employee Id时,将其Id增加到101。这个新的 id 必须立即对其他事务可见。否则会造成重复的Id。
假设所有事务的隔离级别都是READ_COMMITTED。 如何在提交当前事务之前使对 table 的更改对其他事务可见?
Mysql、Oracle 数据库、SqlServer 怎么样?
This new id must be visible to other transactions immediately. Otherwise it will cause duplicate Id.
使用READ_UNCOMMITTED 不会解决您的问题。
假设你的事务读取了最新的id值,然后尝试使用id+1。但是在读取最后一个 id 和尝试使用下一个值之间,一些第三个事务使用了那个值,然后你仍然有一个重复的错误。
这叫一个race condition,就算用READ_UNCOMMITTED也不能速战速决
此外,在任何数据库中使用 READ_UNCOMMITTED 都是一个坏主意。如果其他事务由于某种原因被回滚怎么办?您的事务将读取永远不会 "exist" 的数据,因为它从未提交过。
正是由于这个原因,所有品牌的 RDBMS 都具有在事务范围 之外生成 id 值的功能。
- MySQL: AUTO_INCREMENT
- 甲骨文:SEQUENCE
- 微软SQL服务器:IDENTITY
这些实现的共同点是数据库可以在一种全局范围内生成新的id值,从而保证两个并发事务不会生成相同的值。
您必须使用该机制来生成唯一的 id 值,而不是依赖于 SELECT id+1...
解决方案。 SELECT
受事务隔离影响,因此它看不到最近生成的 id 值,无论是否已提交。但是数据库知道,它永远不会 return 两个不同事务的相同值。
不幸的是,每个实现的语法都不同,因此很难编写出在所有品牌的 SQL 数据库上都能正常工作的 SQL 代码。