首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

对面向对象的1点疑问,百思不得其解

2012-11-06 
对面向对象的一点疑问,百思不得其解学JAVA已经有五年了,当然,我现在已经不是一个职业程序员,但一直还是把J

对面向对象的一点疑问,百思不得其解
学JAVA已经有五年了,当然,我现在已经不是一个职业程序员,但一直还是把JAVA当作自己的一项技能,时时用之。但是关于面向对象设计上有个问题一直弄不懂,特别是用HIBERNATE来做数据库操作时。所以向大家讨教。
问题是这样的:比如一个User类,记载了一个用户的信息,如姓名、年龄、性别等等。
假设有两个管理员同一时间段对某一个用户的资料进行修改,而且只改资料里面的某一项,其他项和进入修改页面时从数据库里读出来的一样。那么
1.A、B管理员都打开该用户的资料修改页面,这个时候,A、B管理员面前的修改页面是数据都是一样的。
2.A管理员改了“年龄”,B管理员“地址”。
3.A管理员保存更新,“年龄”这一项改变了,其他项和数据库里取出时一样。
4.B管理员也保存更新,“地址”这一项改变了,其他项和数据库里取出时一样。
这样的问题是,A管理员更新的“年龄”被B管理员的更新冲掉了,变成了原来的年龄。

这个问题在一些企业应用中还是经常会碰到的,特别是那些需要多人协同,负责采集一个对象的数据的情况。
我在GOOGLE里面也试过,修改自己的Gmail帐号信息,可是还是出现了数据被冲掉的现象。
我现在对这些问题都是采用JDBC直接进行单字段的set XX = ?来解决,但是这样就不是OOD了。
也许对大家来说早就不是问题了,所以想向大家请教! 1 楼 Saito 2009-05-18   对这个User加锁呢?

          同时间段只能一个人修改就行了? 2 楼 tongjian 2009-05-19   这是数据库里的脏读取。在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。
●   未授权读取(Read Uncommitted):允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。
●   授权读取(Read Committed):允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
●   可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻影数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
●   序列化(Serializable):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
       隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

详情参加:http://genghaixu.iteye.com/blog/300567

楼主搞java5年,竟然被这个问题困扰这么久,数据库知识也很重要啊。
    3 楼 tongjian 2009-05-19   tongjian 写道
这是数据库里的脏读取。在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。 ●   未授权读取(Read Uncommitted):允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。 ●   授权读取(Read Committed):允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。 ●   可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻影数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。 ●   序列化(Serializable):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。        隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。 详情参加:http://genghaixu.iteye.com/blog/300567 楼主搞java5年,竟然被这个问题困扰这么久,数据库知识也很重要啊。   

更正,问题应该是Second lost updates problem。可以用乐观锁或悲观锁来解决。 4 楼 seekgirl 2009-05-19   5年还没搞懂?令人惊讶 5 楼 lxdhdgss 2009-05-19   平时自己还有生意要做,JAVA只是凭兴趣,在大学的时候写这个的! 6 楼 king_108 2009-05-19   一般做法,USER 表加个 最后修改时间 和REVISION 字段,UPDATE 的时候判断 读出这2个字段的版本是否跟DB的版本一致,才允许更新操作 7 楼 lxdhdgss 2009-05-19   king_108 写道
一般做法,USER 表加个 最后修改时间 和REVISION 字段,UPDATE 的时候判断 读出这2个字段的版本是否跟DB的版本一致,才允许更新操作

你这个做法很好啊!觉得比较可行。其他的几个回答,我觉得可能是没有明白我的意思吧。我觉得大家可以去试试修改邮箱的个人信息,打开两个浏览器,更改不同的地方,如一个浏览器改地址,一个改联系电话,然后保存,再打开看看是不是地址和联系电话都被修改了,还是一个和原来是一样的。

热点排行