0

我对如何处理持久保存在数据库中的对象的不同生命周期事件感到困惑。我知道这可能因设计而异,但我想知道在这种情况下遵循的任何标准/最佳实践。

说我有这样的User课-

class User {
  int id;
  String name;
}

这种类型的对象代表数据库中的一行。对象由多个线程访问。那么,如何管理对象呢?它的方法是什么?你如何实现删除这样的对象?

假设有两个线程 A 和 B 正在访问同一个用户对象。

// Thread A
User user = UserFactory.getUser(userId);

// Thread B
User user = UserFactory.getUser(userId)
user.delete(); // Or UserFactory.delete(userId)

那么user线程 A 中的对象会发生什么?任何澄清都会非常有帮助。

谢谢!

4

2 回答 2

1

据我了解,就访问对象的线程而言,它对所有人都是免费的,这意味着它们都可以访问同一个对象,除非正在使用同步/锁定。

从我能够从您的伪代码中收集到的内容来看,您删除该对象会将其从系统中完全删除(包括正在访问它的任何线程),但我相信这取决于您删除它的方式。如果您在线程本身中删除一个对象,它应该只从该线程中删除它,但如果您在线程之外删除该对象,它应该从整个系统中删除它。

从我对您的代码的看到来看,我无法确定您是要删除线程 B 中的对象还是在其余代码中删除它,但是无论您要完成什么,我希望我的上述解释对您有所帮助。

于 2013-05-29T19:52:03.063 回答
1

那么线程 A 中的用户对象会发生什么?任何澄清都会非常有帮助。

没有什么。当然,这可能是你的问题。如果您A在删除后尝试在线程中坚持会发生什么可能高度依赖于您使用的 ORM,但我猜假设您使用 Hibernate 会失败,因为线程中UPDATE/DELETE的打开不知道该行是失踪。这种情况经常发生。SessionA

请注意A,只要线程不持久/删除,线程将始终能够自由地改变用户对象而不会出错。该错误只会在您坚持/删除时发生。在这种情况下,首先坚持/删除的人获胜(没有错误)。

人们通过多种方式缓解这个问题:

  1. 默默吞下异常并重新插入对象或忽略
  2. 提升异常(通常是乐观锁定异常)并转换为用户友好的错误。
  3. 一开始就不允许删除。使用布尔列表示删除。
  4. 使您的应用程序实现与您的 ORM 的乐观锁定同步的乐观锁定。
  5. 使用事务和/或synchronized(单个 JVM)
  6. 使用事务和行锁定SELECT ... FOR UPDATE

在大多数情况下,我选择数字 2 和/或 3。数字5是最悲观的,需要大量资源,并可能导致死锁。

于 2013-05-29T20:16:27.433 回答