原来单独使用hibernate的时候,删除一个持久化对象就是用session。delete(id)。但是今天在用spring的模板api的时候看到这样一个方法:
public void delete(Object entity,LockMode lockMode)
想了想,貌似是应该加个锁。。怎么hibernate自己不提供呢?到底有必要为删除加锁么?具体加什么类型的锁呢?

解决方案 »

  1.   

    话说删除某条记录就是一条delete sql语句,一条sql语句是原子的么?
      

  2.   

    一下从2个星星到3个咯。事物是什么,我认为就是一系列的操作要么全部成功要么全部失败(全部操作里面的操作就是原子操作),不可能部分成功部分失败,这就是事物的管理。
    你用了spring,它会帮你管理事物,配置好了就行了。
      

  3.   


    一般碰到这种问题,都代表有几个问题混合起来了:
    一个是事务本身的概念,或者说什么是事务;
    另一个是数据库提供的默认事务隔离级别。
    单就一个delete而言,它必然是原子的,但这不能解决事务这个更大范畴的问题。
      

  4.   


    大侠 我刚了解了一下数据库的锁机制。书上说:当数据库执行delete的时候在表一级加共享锁,为了防止对表结构的更改,然后在当前操作的记录上加排它锁。如果这条delete语句会删除多条记录,这时候及有必要人为加锁了(为了防止脏读、幻读)。但是我想,如果delete语句只删除一条记录,是不是不用人为加锁了?
    虽然这想法有点跑偏,但是我觉得有助于搞清楚原理,还望大侠不吝赐教
      

  5.   

    这个问题以前还真没有注意到。刚研究了下。
    spring 这个方法的实现是这样的。 public void delete(final Object entity, final LockMode lockMode) throws DataAccessException {
    executeWithNativeSession(new HibernateCallback<Object>() {
    public Object doInHibernate(Session session) throws HibernateException {
    checkWriteOperationAllowed(session);
    if (lockMode != null) {
    session.lock(entity, lockMode);
    }
    session.delete(entity);
    return null;
    }
    });
    }从源代码可以看出。spring在删除数据之前,给这个与删除的数据加了一个锁。
    lockMode分为
    NONE : LockMode
    无锁定
    READ : LockMode
    共享锁,指定此所时,在当前事务中数据都是从数据库读取的——而不是从缓存中读取
    UPGRADE_NOWAIT : LockMode
    获取一个提升锁,类似于在orecal中执行了 select for update nowait
    一下就不写了,挺多的,看文档或者源码吧,没有详细解释的还有:
    WRITE : LockMode
    OPTIMISTIC : LockMode
    OPTIMISTIC_FORCE_INCREMENT : LockMode
    PESSIMISTIC_READ : LockMode
    PESSIMISTIC_WRITE : LockMode
    PESSIMISTIC_FORCE_INCREMENT : LockMode他们都再org.hibernate.LockMode中。
    Hibernate中的session中的delete方法并没有提供参数让你设定锁模式。但是《Hibernate in Action 2th》中一直在强调不要使用“删除态”的对象!作为一种最佳实践,Spring 将提供锁定模式加入到了自己的Api中了。就这样。
    至于,事务的隔离级别,乐观锁、悲观锁、内容太多。建议看看书,慢慢消化
      

  6.   

    一般书籍中将对象的状态分为三中,但在《Hibernate in Action 2th》分为了四种多出来的一种原文摘录如下:
    Removed objects
    You can delete an entity instance in several ways: For example, you can remove it
    with an explicit operation of the persistence manager. It may also become available
    for deletion if you remove all references to it, a feature available only in
    Hibernate or in Java Persistence with a Hibernate extension setting (orphan deletion
    for entities).
    An object is in the removed state if it has been scheduled for deletion at the end
    of a unit of work, but it’s still managed by the persistence context until the unit of
    work completes. In other words, a removed object shouldn’t be reused because it
    will be deleted from the database as soon as the unit of work completes. You
    should also discard any references you may hold to it in the application (of
    course, after you finish working with it—for example, after you’ve rendered the
    removal-confirmation screen your users see).