阻塞、锁定和隔离级别之间有什么关系?

发布于 2024-09-13 09:26:30 字数 427 浏览 3 评论 0原文

我对 Oracle 阻塞有一些了解 - 更新如何阻塞其他更新直到事务完成,编写器如何不阻塞读取器等。

我了解悲观和乐观锁定的概念,以及关于丢失更新等的典型银行教科书示例

。还了解 JDBC 事务隔离级别,例如,我们很高兴看到未提交的数据。

然而,我对这些概念如何相关和相互作用有点模糊。例如:

  • Oracle 是否提供悲观或 默认情况下乐观锁定(它 似乎只是阻止了单独的 根据两个实验进行更新 TOAD 会话。)
  • 如果像我怀疑的那样,这些是 应用程序级别的概念,为什么 我不厌其烦地实施了 当我可以让时锁定策略 数据库同步事务 无论如何更新?
  • 当除我的应用程序之外的其他客户端使用不同的隔离级别进行访问时,事务隔离级别(我在连接上设置的)如何改变数据库行为。

任何能够澄清这些主题的文字将不胜感激!

I understand a little about Oracle blocking - how updates block other updates till the transaction completes, how writers don't block readers etc.

I understand the concept of pessimistic and optimisic locking, and the typical banking textbook examples about losing lost updates etc.

I also understand the JDBC transaction isolation levels where we might say, for instance, we are happy with seeing uncommitted data.

I'm a bit fuzzy however about how these concepts are related and interact. For instance:

  • Is Oracle providing pessimistic or
    optimistic locking by default (it
    just seems to block the seperate
    update based on experiments in two
    TOAD sessions.)
  • If, as I suspect, these are
    application level concepts, why would
    I go to the trouble of implementing a
    locking strategy when I can let the
    database synchronise transaction
    updates anyway?
  • How do transaction isolation levels (which I set on the connection) alter the database behaviour when other clients besides my application be accessing with different isolation levels.

Any words to clarify these topics would be really appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怪我入戏太深 2024-09-20 09:26:31
  • Oracle 允许任一类型的锁定 - 您构建应用程序的方式决定了所使用的内容。回想起来,这实际上并不是一个数据库决定。

  • 大多数情况下,Oracle 的锁定足以满足与数据库的有状态连接。在无状态应用程序(例如 Web 应用程序)中,您无法使用它。在这种情况下,您必须使用应用程序级锁定,因为锁定适用于会话。

  • 一般情况下你不需要担心这个问题。在 Oracle 中,读取器永远不会阻止写入器,写入器也永远不会阻止读取器。 Oracle 的行为不会随着各种 ANSI 隔离级别的变化而改变。例如,Oracle中不存在“脏读”这样的事情。 Tom Kyte 指出,允许脏读的精神是为了避免阻塞读,这在 Oracle 中不是问题。

我强烈建议您阅读 Tom Kyte 的优秀著作“Expert Oracle Database Architecture”,其中对这些主题和其他主题进行了非常清晰的阐述。

  • Oracle allows for either type of locking - how you build your app dictates what is used. In retrospect, it's not really a database decision.

  • Mostly, Oracle's locking is sufficient in a stateful connection to the database. In non-stateful apps, e.g., web apps, you cannot use it. You have to use application level locking in such situations because locking applies to a session.

  • Usually you don't need to worry about it. In Oracle, readers never block writers, and writers never block readers. Oracle's behavior does not change with the various ANSI isolation levels. For example, there is no such thing as a "dirty read" in Oracle. Tom Kyte points out that the spirit of allowing dirty reads is to avoid blocking reads, which is not an issue in Oracle.

I would strongly recommend reading Tom Kyte's excellent book "Expert Oracle Database Architecture", in which these and other topics are addressed quite clearly.

梦醒灬来后我 2024-09-20 09:26:31

乐观锁基本上是“我只会在修改数据时锁定数据,而不是在读取数据时锁定数据”。问题是,如果您不立即锁定数据,其他人可以在您之前更改它,并且您正在查看旧新闻(并且可以盲目地覆盖您读取数据和更新数据之间发生的更改。 )

悲观锁定是在读取数据时锁定数据,以便在您决定更新数据时确保没有人更改它。

这是一个应用程序决策,而不是 Oracle 决策,因为:

SELECT x, y, z FROM table1 WHERE a = 2

不会锁定匹配记录,但

SELECT x, y, z FROM table1 WHERE a = 2 FOR UPDATE

会锁定。因此,您必须决定是否接受乐观锁定

SELECT x, y, z FROM table1 WHERE a = 2

...时间流逝...

UPDATE table1
   SET x = 1, y = 2, z = 3
 WHERE a = 2

(您可能覆盖了其他人同时所做的更改)

或者需要悲观:

SELECT x, y, z FROM table1 WHERE a = 2 FOR UPDATE

...时间流逝...

UPDATE table1
   SET x = 1, y = 2, z = 3
 WHERE a = 2

(您确定自您查询以来没有人更改过该数据。)

请在此处检查 Oracle 中可用的隔离级别。
http://download.oracle.com/文档/cd/B19306_01/server.102/b14220/consist.htm#CNCPT621

Optimistic locking is basically "I'll only lock the data when I modify the data, not when I read it". The gotcha is that if you don't lock the data right away, someone else can change it before you do and you're looking at old news (and can blindly overwrite changes that have happened between when you read the data and updated it.)

Pessimistic locking is locking the data when you read it so that you'll be sure that no one has changed it if you do decide to update it.

This is an application decision, not an Oracle decision as:

SELECT x, y, z FROM table1 WHERE a = 2

will not lock the matching records but

SELECT x, y, z FROM table1 WHERE a = 2 FOR UPDATE

will. So you have to decide if you're ok with optimistic locking

SELECT x, y, z FROM table1 WHERE a = 2

...time passes...

UPDATE table1
   SET x = 1, y = 2, z = 3
 WHERE a = 2

(you could have overwrote a change someone else made in the meantime)

or need to be pessimistic:

SELECT x, y, z FROM table1 WHERE a = 2 FOR UPDATE

...time passes...

UPDATE table1
   SET x = 1, y = 2, z = 3
 WHERE a = 2

(you're sure that no one has changed the data since you queried it.)

Check here for isolation levels available in Oracle.
http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/consist.htm#CNCPT621

断肠人 2024-09-20 09:26:31

Oracle 始终处理悲观锁定。也就是说,它会在更新时锁定记录(如果涉及密钥,您还可以锁定删除和插入)。您可以使用 SELECT....FOR UPDATE 来增强悲观锁定策略。

实际上,任何以事务方式工作的数据库/存储引擎都必须执行某种形式的锁定。

SERIALIZABLE 隔离级别更接近于乐观锁定机制。如果事务尝试更新自事务开始以来已更新的记录,它将引发异常。然而,它依赖于数据库会话和最终用户会话之间的一对一。

随着连接池/无状态应用程序变得普遍,特别是在用户活动频繁的系统中,长时间占用数据库会话可能是一个糟糕的策略。乐观锁定是首选,Oracle 的更高版本通过 ORA_ROWSCN 和 ROWDEPENDENCIES 项支持此操作。基本上,它们可以更轻松地查看自您最初/最后一次查看记录以来是否已更改。

由于数据库会话和用户会话之间的一对一关系已成为遗留问题,应用程序层保留了更多的“用户会话”状态,因此更加负责检查用户所做的五/十个选择几分钟前仍然有效(例如,这本书是否还有库存,或者是否有其他人购买)。

Oracle ALWAYS handles pessimistic locking. That is, it will lock a record when it is updated (and you can also hit locks for deletes and inserts if there is a key involved). You can use SELECT....FOR UPDATE to augment the pessimistic locking strategy.

Really any database/storage engine that works transactionally must do some form of locking.

The SERIALIZABLE isolation level is much closer to a optimistic locking mechanism. It will throw an exception if the transaction tries to update a record that has been updated since the start of the transaction. However it relies on a one-to-one between the database session and the end user session.

As connection pooling/stateless applications become prevalent, especially in systems with heavy user activity, having a database session tied up for an extended period can be a poor strategy. Optimistic locking is preferred and later versions of Oracle support this with the ORA_ROWSCN and ROWDEPENDENCIES items. Basically they make it easier to see if a record has been changed since you initially/last looked at it.

As that one-to-one relationship between a database session and a user-session has become legacy, the application layer has preserved more of the 'user-session' state and so become more responsible for checking that choices the user made five/ten minutes ago are still valid (eg is the book still in stock, or did someone else buy it).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文