我在同一个事务中,
先用HibernateTemplate.save()了数据
然后用HibernateTemplate.execute,手写SQL去查询,此查询涉及到上一步save的数据
但是就是读不到上一步save的数据
求高手解答。

解决方案 »

  1.   

    说明一下 我是一个biz里面调用了另一个biz的方法
    两个biz配的不同的dao。
    我们的框架是系统启动时就把biz实例化好了。
      

  2.   

    save()后commit()一下。或者看你save的对象在你查询的时候是处于什么状态?如果是持久化状态应该可以查出来数据,如果处理游离状态应该不可以吧。我认为是这样的,还等高手确定一下。
      

  3.   

    我断点调式单走完save方法 还没走完整个事务 数据库里面是查不出数据的。再申明下:我们的框架是申明式事务管理,事务传播机制是:PROPAGATION_REQUIRED
    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="is*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="val*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="do*">
    PROPAGATION_REQUIRED,-IEMSRollBackException
    </prop>
    <prop key="add*">
    PROPAGATION_REQUIRED,-IEMSRollBackException
    </prop>
    <prop key="delete*">
    PROPAGATION_REQUIRED,-IEMSRollBackException
    </prop>
    <prop key="update*">
    PROPAGATION_REQUIRED,-IEMSRollBackException
    </prop>
    <prop key="audit*">
    PROPAGATION_REQUIRED,-IEMSRollBackException
    </prop>
    <prop key="save*">
    PROPAGATION_REQUIRED,-IEMSRollBackException
    </prop>
    <prop key="close*">
    PROPAGATION_REQUIRED,-IEMSRollBackException
    </prop>
    <prop key="unClose*">
    PROPAGATION_REQUIRED,-IEMSRollBackException
    </prop>我这个事务里面还有个delete方法,同样我之后的那个查询方法查询的数据也涉及到这个delete方法delete掉的数据,delete方法是用HibernateTemplate.execute执行的,同样走完这个方法,删除掉的数据也是没提交的,但是我之后的那个查询方法能读到删除掉的数据。我的疑问是:难道HibernateTemplate.save()和HibernateTemplate.execute不是在一个事务里,就是说难道他们底层的session connection不一样???public Gdj2SubValSysBO addFromSelected(Object[] objArr, Gdj2SubContrBO contrBO) 
    throws IllegalAccessException, InvocationTargetException, IEMSRollBackException {
    String contrID = contrBO.getID();
    Gdj2SubValSysBO subBO;
    try {
    subBO = findRoot(contrBO,true);
    } catch (IEMSNotRollBackException e) {
    throw new IEMSRollBackException(e);
    }
    List delArr = new ArrayList();
    List addArr = new ArrayList();
    if(objArr!=null) {
    List list = new ArrayList();
    List deleteList = new ArrayList();//以后编制分包时勾掉的测量体系

    for(int i=0;i<objArr.length;i++) {
    Gdj2ValSysBO mainBO = (Gdj2ValSysBO)objArr[i];
    Gdj2SubValSysBO newBO = new Gdj2SubValSysBO();
    BeanUtils.copyProperties(newBO, mainBO);
    newBO.setContrID(contrID);
    newBO.setValID(mainBO.getID());
    if(mainBO.getHasSub() == 0) {
    deleteList.add(newBO);
    delArr.add(mainBO);
    } else {
    list.add(newBO);
    addArr.add(mainBO);
    }
    }

    try {
    insertPacks(deleteList,delArr.toArray(),contrID);
    insertPacks(list,addArr.toArray(),contrID);
    doAddSelected(list,subBO.getID(),subBO.getContrID());
    doDeleteSelected(deleteList);
    IProjectBiz biz = (IProjectBiz)getBiz(ProjectBO.class);
    biz.updateSynchro(contrID);
    } catch (IEMSException e) {
    throw new IEMSRollBackException(e);
    }//
    } return subBO;
    }
      

  4.   

    就是这样的 
    防止脏读
    你在sqlplus里面 插入一条数据
    在commit之前
    其他用户是读不到你插入的数据的
    所以必须提交事务
    数据才能真正的插入到数据库中
    否则他只停留在缓存里 也就是hibernate中的非持久化状态
      

  5.   

    能确信是同一个事务吗?如果是同一个事务肯定可以读到,
    maybe根本没有同步到数据库 而是缓存在了实体管理器中
    要不你调用下flush()方法 和数据库同步下子呢;
      

  6.   

    你都没有commit的东西,能查得到么?
    是不是应该save 做为一个事务来处理,一个事物只允许提交一次
      

  7.   

    你的切面呢
    aop
    advice
      

  8.   

    flush 以后如果出现异常 之前的能回滚吗?
    确信是同一个事务。
    因为我断点走完save方法数据库里面是没有提交的。
    走完后面的查询方法 数据库里面也是没有提交之前save进去的数据
    走完整个方法以后才提交
      

  9.   

    但是我这是同一个事务啊。
    我在数据库里面直接用insert  和 select写在一个事务里面
    select也是可以读出数据的
    但是如果另开一个session就会像你说的那样。
      

  10.   

    1 事务级别是啥
    2 save的事物有无正确落实
    3 save和query不能在一个事物中做
      

  11.   

    默认的事务隔离级别,ORACLE
    按照我们框架的事务传播机制save是在外围事务中执行的
    save和query不能在一个事务中做?是说 同一个事务中,save的数据 query是查不到的?
      

  12.   

      嗯 楼上不少都说的对着呢 ,save 完 commit 一下,或flush 一下,就能拿到了,这样save 完之后数据才同步到了数据库!! 实实在在的数据 
      

  13.   

    flush已经解决问题,commit不行吧?如果我后面的操作出异常了,之前的又commit了 还能回滚吗?
      

  14.   

    正常!为了防止脏读,在update时,数据更改并不会立即反应在数据库里面。仅仅将要修改的数据放在缓冲区等待真正写入。当发出commit命令的时候,本次事务所有修改的数据才真正写入数据库。在commit之前,读操作是允许的,所以读到的是修改前的操作。hibernate中有对数据进行持久化的方法,仅save()是不行的,只要在代码中调用就可以读出修改后的数据了。
      

  15.   

    以前也遇到相同的问题,后来是spring中配置了BeanName自动代理就好了。
      

  16.   


    flush 可以回滚 因为此时事务并未提交 只有commit之后才是不可回滚的
    flush 的目的是把数据写入数据库 flush 之前可能你的数据还在服务器缓存中 数据库根本就不知道他的存在
    flush 虽然写入了数据库 只要你没commit 都是可以回滚的
    注:flush 是必须要做的,就算你不写 管理器也会默认回调,一般有三个时机会执行该方法
    1、你显式调用时
    2、执行查询之前
    3、提交之前
    后两种情况和你配置有关的 如果按你说的flush可以解决问题的话 可能就是你配置的是commit 时才同步。
     
      

  17.   

    别汗呀!到底一个事物里是否可以save还未commit时读取到数据呀!!困惑
      

  18.   

    可以的,读取数据时的方法一般有重载的,在后面加一个事务的参数就可以拿到没有commit的数据
      

  19.   

    可以的,读取数据时的方法一般有重载的,在后面加一个事务的参数就可以拿到没有commit的数据加什么参数解决
      

  20.   

    可以的,读取数据时的方法一般有重载的,在后面加一个事务的参数就可以拿到没有commit的数据加什么参数解决兄弟,求教育啊,= =话说一半木解决
      

  21.   

    创建事务时,选取以上的方式,即可在事务中读取没有提交的数据,但是要你的数据支持,oracl和sqlserver都可以,至于mysql以前是不支持的,不知道现在被oracl接手以后变成什么了。这个方面的术语叫“事务隔离级别”,你可以搜搜相关的资料,去年我搞了好长时间呢。
      

  22.   

    可以的,读取数据时的方法一般有重载的,在后面加一个事务的参数就可以拿到没有commit的数据加什么参数解决给你个提醒吧,楼主早死了
      

  23.   

    可以的,读取数据时的方法一般有重载的,在后面加一个事务的参数就可以拿到没有commit的数据加什么参数解决兄弟,求教育啊,= =话说一半木解决
    答案在上面,我贴的图中