数据库锁问题

xianaofei 2011-03-12 09:32:51
悲观锁和乐观锁 直接用hibernate可以很方便的解决

我想问的是在开发的时候如果不用hibernate怎么来解决呢。
我的理解是这样的,数据库表中加一个字段比如 isusing字段 默认值0 表示没有占有,当有人编辑操作时修改其状态 1 ,操作完成之后再修改为默认值 0。
但是如果我刚点击编辑操作,isusing变成了1 而突然终止了操作,比如死机 浏览器突然关闭。
如果使用事务,就是说我isusing字段再操作完之后再提交。这样就会产生冲突,你点击了操作,我也点击了操作不就冲突了么。
因为以前没有详细接触过,希望用过的高手说一下思路 谢谢。
...全文
143 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
宁静-夏天 2011-03-30
  • 打赏
  • 举报
回复
回过头来看了下这个帖子,感觉楼主还是没搞明白hibernate在事物处理上提供了什么样的支持,乐观锁hi是通过时间戳来支持。乐观锁的实现是多样的,楼上邱明所说的也是一种,只能证明version不同就可以了。

悲观锁不会通过client端软体来做的。
第一:通道不唯一,可以有多个APP共享一个DB
第二:client在维护数据的锁时,需要同一时间只让一个线程去操作锁标志量,而且这个DB访问必须是block同步操作。而这种场景必然会形成访问瓶颈。因为会将数据库连接的开销放在同步块中。
第三:人为增加了client的复杂度,放着数据库好好东西不用,做个更烂的出来,很没有道理啊。

数据库给出了同步的能力,提供了悲观锁,各种事物隔离级别,double submit的功能能,没必要自己去实现,也不可能比数据库提供的能力要好。

jdbc的API暴露了DB的事物能力,hibernate是基于jdbc开发的ORM映射DB访问framework,并不是由hibernate实现了悲观锁。

而且事物处理本来就是由人为的剥离了,transaction只是利用jdbc暴露的事物接口,或者hibernate session封装jdbc的事物接口来管理事物而已。

所以楼主没有使用hibernate跟事物存在不根本没有半点关系,事物本来就在哪里,hibernate你用它在,你不用它也在。只是transactionManager的种类因为调用接口的不同有所区分。
例如:jdbcTransactionMananger,HibernateTransactionMananger。
orange620 2011-03-19
  • 打赏
  • 举报
回复
http://www.blogjava.net/loocky/archive/2006/11/15/81138.html

qm4050 2011-03-19
  • 打赏
  • 举报
回复
你所说的是乐观锁吧,我从网上查了一了下,自己也学习了一下。
你可以在读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。 <br>对于上面修改用户帐户信息的例子而言,假设数据库中帐户信息表中有一个version 字段,当前值为 1 ;而当前帐户余额字段(balance)为 $100 。 <br>1 操作员 A 此时将其读出(version=1),并从其帐户余额中扣除 $50($100-$50)。 <br>2 在操作员 A 操作的过程中,操作员 B 也读入此用户信息(version=1),并从其帐户余额中扣除 $20 ($100-$20)。 <br>3 操作员 A 完成了修改工作,将数据版本号加一(version=2),连同帐户扣除后余额(balance=$50),提交至数据库更新,此时由于提交数据版本大于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。 <br>4 操作员 B 完成了操作,也将版本号加一(version=2)试图向数据库提交数据(balance=$80),但此时比对数据库记录版本时发现,操作员 B 提交的数据版本号为 2 ,数据库记录当前版本也为 2 ,不满足“ 提交版本必须大于记录当前版本才能执行更新“ 的乐观锁策略,因此,操作员 B 的提交被驳回。这样,就避免了操作员 B 用基于 version=1 的旧数据修改的结果覆盖操作员 A 的操作结果的可能。
dracularking 2011-03-14
  • 打赏
  • 举报
回复
当前使用状态1可以立即提交啊,等真正事务完成之后再回复为0
xianaofei 2011-03-14
  • 打赏
  • 举报
回复
恩 楼上两位讲的偏于理论了
有没有再开发中处理的例子呢
在实际开发中用的
宁静-夏天 2011-03-12
  • 打赏
  • 举报
回复
楼主所说的乐观锁的做法,hib是用时间戳做的,是更新数据时,那获取的数据的时间戳和数据库中将要被修改的数据的时间戳对比,然后决定是否修改。典型的CAS模式,比较 and 赋值 的做法。

用标志量1,0来判断太过简单了,应该会出现很多问题,而且楼主是先更新状态标志为1,这个就是完全性的所记录的意图了,但这个是由client端来做的锁记录,估计多线程场景很多哦。

最简单的问题就是,两条记录同时获取一条记录,并同时把该记录的状态位更新为1(获取记录时都是在状态位更新为1前),这样还是有两个线程同时修改一个数据,数据并没有独占。问题大大有!

所以悲观锁主要是依赖数据库的锁机制。
楼主可以了解下数据库的事物隔离级别,还有事物传播行为。
runer 2011-03-12
  • 打赏
  • 举报
回复
对于悲观锁,不管hibernate还是别的什么,都需要利用数据库系统的自身锁机制

不然无法保证事务的完整性

所以说,离开hibernate,本质上还是利用事务机制

不管终止操作,死机等,最终还是事务机制自身在起作用,是正确提交,还是错误回滚,超时回滚

由数据库系统自身根据你的事务机制来自行决定

至于你说的冲突,那是始终存在的,你用hibernate也存在。

只要存在资源竞争和冲突就会有锁,就会有独占。

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧