lz 经常在 v 站评论帮助他人, 很少发帖, 这次借贵宝地, 请教路过的各位大佬谈谈看法, 解答一下疑惑:
oracle 在具体实践中是否会考虑 "不可重复读", "幻读" 问题, 又是如何去解决的呢?
下面是楼主做的准备工作:
事务的隔离级别
存在的问题
解决方法
楼主查过 oracle 官网的文档, 似乎也没有具体的答案, db2 的资料多一些, 直接修改隔离级别为 "序列化读" 也不现实.
1
sun1991 2021-09-06 16:39:00 +08:00
给个具体点的例子吧?
|
2
stach OP @sun1991
这里有个 MySQL 的例子: https://segmentfault.com/a/1190000016566788, 我这里是没有 oracle 的. lz 是互联网从业者, 几乎都使用 MySQL 数据库, 所以疑惑 oracle 从业者的实践姿势 |
3
stach OP 可能 v 站大多是用 MySQL 的兄弟吧, 这个问题石沉大海了 :(
|
4
sun1991 2021-09-07 09:42:32 +08:00 1
以下是我的个人理解:
Oracle 一共只有两种隔离级别 (抛开 readonly 不谈). Serialize 一般不用. 常用的也就是 read committed. Oracle 的锁是加在物理 row 上面, 也就是说, 如果 row 不存在, 那么就不能加锁. 所以 Oracle 没有 MySQL 那么多的弯弯绕. 如果你要应对不可重复读, 幻读问题, 那么老老实实地用 serialize 隔离级别. Oracle 的 serialize 隔离级别其实是一种乐观锁, 它限制的是自己的 session 而非其它 session 的写操作, 意思是当检测到自己 session 违反了 serialize 隔离级别的限制, 就报错. 总之, Oracle 的优化目标是尽可能使得所有的 read 操作尽快完成, 所以能不锁的一概不锁. |
5
stach OP @sun1991
赞同老哥的说法, 不能用 MySQL 的理论去套 oracle, 开启事务的时候设定隔离级别为 serialize 不失为解决 不可重复读, 幻读的好方法. 其实 MySQL 官方的 Python Connector 库开启事务的时候, 就有指定隔离级别的参数, 只是我们几乎都习惯了固定为 REPEATABLE READ. ```python def start_transaction(self, consistent_snapshot=False, isolation_level=None, readonly=None): """Start a transaction This method explicitly starts a transaction sending the START TRANSACTION statement to the MySQL server. You can optionally set whether there should be a consistent snapshot, which isolation level you need or which access mode i.e. READ ONLY or READ WRITE. For example, to start a transaction with isolation level SERIALIZABLE, you would do the following: >>> cnx = mysql.connector.connect(..) >>> cnx.start_transaction(isolation_level='SERIALIZABLE') Raises ProgrammingError when a transaction is already in progress and when ValueError when isolation_level specifies an Unknown level. """ ``` |
6
Hozzz 2021-09-11 01:21:29 +08:00 1
select for update
|