虽然我不会我也看出了第一种配置是有问题的,你把事务配在addPerson()方法上,那你两个addPerson()方法之间不属于一个事务了...你要把两个dao层的方法放到一个事务里,事务应该配置在封装两个dao的方法上,就想你下面配在UserServiceImpl一样

解决方案 »

  1.   

    那spring注解 就不能用三层架构了吗?@Transactional到底应该标注在什么地方?
      

  2.   

    注解也可以三层架构啊,看具体业务需求,我们不怎么用事务,不过我想事务加service层好点吧。
      

  3.   

    这个好像是可以的, @Transactional
     public void addPerson() throws Exception {
     sysUserDao.addPerson();
     sysUserDao.addPerson2();
     }
    这个你相当产生了两个方法的对象,在sysUserDao.addPerson();中添加数据的时候,并没有出现回滚的条件,自然就会有一条数据被插入到数据库,sysUserDao.addPerson2();的时候查询到主键冲突,就会回滚该对象,你后面的那个方法都只是产生一个方法对象。你可以测试一下,这是我的观点。
      

  4.   

    我觉得可能是在调用的这两个方法,jdbcTemplate是不一样的,所以没办法回滚,但是我想知道,service层到底可不可以调Dao层方法,可不可以不写sql语句,Dao我是用JDBC对数据库进行封装了的,我的意思是,简单的在业务层可以调用Dao层简单的增删改查方法。
      

  5.   

    主要是你修改之后的@Transactional那时没有抛出异常,spring必须捕获到你抛出异常才会进行回滚,可以试试:@Transactional
    public void addPerson() throws Exception {
    try{
    jdbcTemplate.update("insert into sysuser values(?,?)", new Object[] {
    "1", "1" }, new int[] { Types.VARCHAR, Types.VARCHAR });jdbcTemplate.update("insert into sysuser values(?,?)", new Object[] {
    "1", "2" }, new int[] { Types.VARCHAR, Types.VARCHAR });
    }
    }catch(Exception e){
    throw e;//你这里必须捕获后重新抛出,或者直接抛出也行,那么就一定不会执行成功了。
    }
    }你在前面addPerson那时有抛出异常,但奇怪的是你到后面合成一个就忘记抛了。
      

  6.   

    事务回不回滚与几层没有关系,与什么所谓模式也没有关系。
    <bean id="userServiceImpl" class="mwr.service.UserServiceImpl">
    <property name="dataSource" ref="dataSource"></property>
    </bean>上面这句是把类UserServiceImpl 也交给spring去管理了。之前的不好用,因为没有把它配置在bean.xml里。
    UserServiceImpl里面加了那么多注解,当然要配置在bean.xml里,交给spring去管理。
      

  7.   

    DAO层也添加事务声明,会导致和services的事务不能保持一致吧
    而且你第一种DAO层的方法定义的是抛出RuntimeException 才会回滚吧
      

  8.   

    @Transactional
    用于业务层DAO层只是用于读取数据,操作数据的。例如你的业务(service)层有一个修改用户信息,并且删除用户的方法。@Transactional
    public list<user> getUserInfo(){
    try{
    dao层.修改方法()
    dao层.删除方法()
    }catch(RuntimeException e){
    }}
      

  9.   

    spring 捕获的是RuntimeException 异常才会回滚。而且你要注意你使用的数据库如果使用mysql的数据库。数据库表类型除了InnoDB和DBD类型外,其他是不支持事务的。
      

  10.   

    通常情况下  不建议把事务控制放在DAO层。业务层就干业务层的事情。数据访问层就干只关心数据的读写。充分体现MVC架构
      

  11.   

    你这段代码是service里的吗?我不想在service里执行sql语句,你这种方法根本不行
      

  12.   

    我肯定不能把dataSource传给service啊,我用他主要是负责业务的,操作数据库的方法我是想在dao层封装的,你明白吗?
      

  13.   

    我不在dao层加事务声明也不管用,至于抛出异常,即使抛出RuntimeException 异常,也不管用
      

  14.   

    @Transactional(rollbackFor = RuntimeException.class,propagation=Propagation.REQUIRED)
    public void addPerson() throws Exception {
    jdbcTemplate.update("insert into sysuser values(?,?)", new Object[] {
    "1", "1" }, new int[] { Types.VARCHAR, Types.VARCHAR });throw new Exception("checked 例外");
    }
    @Transactional(rollbackFor = RuntimeException.class,propagation=Propagation.REQUIRED)
    public void addPerson2() throws Exception {jdbcTemplate.update("insert into sysuser values(?,?)", new Object[] {
    "1", "2" }, new int[] { Types.VARCHAR, Types.VARCHAR });
    throw new Exception("checked 例外2");
    }
    }你将事务配在addPerson()和addPerson2()上,这样你下面在
    public void addPerson() throws Exception {
    sysUserDao.addPerson();
    sysUserDao.addPerson2();
    }调用两次插入同样主键,这根本就不是一个事务怎么回滚?这分别是两次事务,不过第一次成功了,第二次失败了。
    你按第一种配置这样试试看看会不会回滚
    @Transactional(rollbackFor = RuntimeException.class,propagation=Propagation.REQUIRED)
    public void addPerson() throws Exception {
    jdbcTemplate.update("insert into sysuser values(?,?)", new Object[] {
    "1", "1" }, new int[] { Types.VARCHAR, Types.VARCHAR });
    jdbcTemplate.update("insert into sysuser values(?,?)", new Object[] {
    "1", "2" }, new int[] { Types.VARCHAR, Types.VARCHAR });
    throw new Exception("checked 例外");
    }
      

  15.   

    我不想把事务控制在Dao层,也不想再service层写sql语句,我要把持久化封装在Dao
      

  16.   

    那你就把事务控制在service层不就行了,像你上面第二种写法,有问题?