浏览 3925 次
锁定老帖子 主题:数据库事务和并发
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-11-06
为了避免上述错误, 可采用如下策略: 使用完全隔离的事务
乐观锁 其原理就是事务在执行更新操作前先判断更新数据是否被修改。可以通过版本号、时间戳、对象状态等来判断是否已被修改。一般情况下,尽量使用版本号来判断,只在对老系统进行升级且无法使用版本号的前提下, 才会使用时间戳。 关于乐观锁,jdbc和ibatis需要用户自己单独实现。jdo和hibernate无需用户单独实现,只需要简单的配置就可以使用。 在如下情况下,不推荐使用乐观锁: 数据库模式不支持乐观锁(对老系统进行升级) 应用程序必须保证能够更新读取的记录 应用程序要求读取的一致性 悲观锁 悲观锁机制会假设更新冲突总会发生。所以不管冲突是否真的会发生,它都会枷锁。悲观锁能在一定程度上防止读取数据的不一致性。但当有insert操作时,读取结果可能不一致。 用法 select ... for update 补充:关于隔离级别,可以通过spring拦截器或jdbc datasource来实现。 通知并发更新 在业务层捕获/处理dao异常并不是一件明智的事,幸运的是,spring提供了一个扩展,能够自动翻译jdbc、hibernate、jdo抛出的数据访问异常。 但是,spring在处理此操作时有一个缺陷,就是spring无法出由oracle产生的部分错误识别码。如:ORA-00060 ORA-08177等。针对上述情况,我们可以通过扩展 SQLErrorCodeSQLExceptionTranslator来弥补。 使用jdo和hibernate处理并发更新 使用起来相对比较简单,只需做简单的配置,jdo/hibernate就可自动产生对应的sql语句。 用jdo处理并发更新 <version strategy="version-number" column="XXX"/> 或 <version strategy="timestamp" column="XXX"/> 或 <version strategy="stateimage" column="XXX"/> hibernate 处理并发更新 使用乐观锁 <version name="version" clumn="XXX"/> 使用<class>元素的乐观锁属性来定义hibernate采用字段比较来实现乐观锁检查。 <class dynamic-update="true" optimistic-lock="dirty"...> 使用悲观锁 通过调用session.load() session.lock和query.setLockMode()这些方法,锁住对象对应的数据表里的记录。 从数据并发失败中恢复 当并发更新失败,在表示层打印出来不是明智之举。我们应该想办法重新提交事务。一种方式是使用try catch块,不过这种方式将导致业务逻辑代码中含有大量的try catch块。另一种方式是使用Aop interceptor重试事务 注:当应用程序调用了非事务性的api或做了不能恢复的事情(比如发了邮件),事务就不能自动回滚和恢复。在这些情况下,必须在应用程序级别写代码解决。 小结: 如果你使用的是jdbc和ibatis,你必须自己实现乐观锁和悲观锁。相比之下,jdo和hibernate内置的乐观锁和悲观锁会自动产生对应的sql语句。你可以通过一个类的O/R映射来启动乐观锁。关于悲观锁, jdo需要设置PersistenceManagerFactory属性,hibernate需要在装载对象或执行查询的时候调用一个方法。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |