search

Home  >  Q&A  >  body text

java - mybatis怎么处理事务问题

我用的mybatis是基于SqlSessionTemplate实现的,如下:

@Repository("daoSupport")
public class DaoSupport implements BaseDAO {

    @Resource(name = "sqlSessionTemplate")
    private SqlSessionTemplate sqlSessionTemplate;
    
    /**
     * 保存对象
     * @param str
     * @param obj
     * @return
     * @throws Exception
     */
    public Object save(String str, Object obj){
        return sqlSessionTemplate.insert(str, obj);
    }
    
    /**
     * 批量更新
     * @param str
     * @param obj
     * @return
     * @throws Exception
     */
    public Object batchSave(String str, List objs){
        return sqlSessionTemplate.insert(str, objs);
    }
    
    /**
     * 修改对象
     * @param str
     * @param obj
     * @return
     * @throws Exception
     */
    public Object update(String str, Object obj){
        Integer count=sqlSessionTemplate.update(str, obj);

@Service

public class OrderInfoService  {

    @Resource(name = "daoSupport")
    private DaoSupport dao;
        
    
    @SuppressWarnings("unchecked")
    public List<PageData> getPerson() {
         List<PageData> a =(List<PageData>)dao.findAllList(
                    "OrderInfoMapper.getOrderInfo");
         return a;
            
        }
    public void save(PageData pd){
        dao.save("OrderInfoMapper.saveOrderInfo", pd);
    }
    public void update(PageData pd){
        dao.update("OrderInfoMapper.updateOrder", pd);
    }
    
    @SuppressWarnings("unchecked")
    public List<PageData> list(PageData pd){
        return (List<PageData>)dao.findForList("OrderInfoMapper.getOrderInfo", pd);
    }

在xml文件里面写对应sql的Mapper,
我想在调用service层的方法操作数据库时,几条sql语句同时commit,其中有一条失败则全部不执行,就和jdbc那样先设置不自动commit,然后在commit那种,要在哪里配置或调用啥方法实现?

伊谢尔伦伊谢尔伦2802 days ago650

reply all(4)I'll reply

  • 大家讲道理

    大家讲道理2017-04-18 10:53:03

    Please use Baidu spring’s transaction management

    The first one is to configure transaction management rules. You can search on Baidu on how to write it specifically. I can’t explain it in one or two sentences

        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
        <aop:config>
            <aop:pointcut id="interceptorPointCuts" expression="execution(* com.web..*.services..*Impl.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts"/>
        </aop:config>
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
                <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
                <tx:method name="insert*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
                <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>for="java.lang.Exception"/> -->
            </tx:attributes>
        </tx:advice>

    The second way to use the annotation @Transactional

       <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
        <!--声明使用注解式事务-->
        <tx:annotation-driven transaction-manager="transactionManager"/>

    reply
    0
  • 高洛峰

    高洛峰2017-04-18 10:53:03

    Programmatic Transaction Management MyBatis SqlSession provides you
    with specific methods to handle transactions programmatically. But
    when using MyBatis-Spring your beans will be injected with a Spring
    managed SqlSession or a Spring managed mapper. That means that Spring
    will always handle your transactions.

    You cannot call SqlSession.commit(), SqlSession.rollback() or
    SqlSession.close() over a Spring managed SqlSession. If you try to do
    so, a UnsupportedOperationException exception will be thrown. Note
    these methods are not exposed in injected mapper classes.

    Regardless of your JDBC connection's autocommit setting, any execution
    of a SqlSession data method or any call to a mapper method outside a
    Spring transaction will be automatically committed.

    If you want to control your transactions programmatically please refer
    to chapter 10.6 of the Spring reference manual. This code shows how to
    handle a transaction manually using the PlatformTransactionManager
    described in section 10.6.2.

    mybatis-spring

    reply
    0
  • 高洛峰

    高洛峰2017-04-18 10:53:03

    Spring does not seem to allow manual submission of transactions, the Spring container will automatically manage transactions!

    reply
    0
  • 阿神

    阿神2017-04-18 10:53:03

    
    
    //使用事务处理,订单及货物订单必须同时插进2个表里面
    @Transactional(rollbackFor=Exception.class)
    public void save(PageData pd,Map<String,Integer> map,String uuid,int Uid){
        dao.save("OrderInfoMapper.saveOrderInfo", pd);
        OrderGood orderGood=new OrderGood();
        for(String gid:map.keySet()){
            Goods good=goodService.findOne(gid);
            orderGood.setGname(good.getGname());
            //Integer a=map.get(gid);
            orderGood.setOgamount(map.get(gid));
            orderGood.setGid(Integer.parseInt(gid));                
            orderGood.setOgtotalprize(map.get(gid)*good.getGprice());
            orderGood.setUid(Uid);
            orderGood.setOid(uuid);
            dao.save("OrderInfoMapper.saveOrderGood", orderGood);
            }          
                   
    }
    使用@Transactional  注解则成功解决问题,此注解是spring 的事务管理,使用前先配置如下:
    
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
        <!--声明使用注解式事务-->
        <tx:annotation-driven transaction-manager="transactionManager"/>
            
        
        
        只需要在service层方法中执行多条mybatis的mapper并加上注解即可,发生异常则此方法的事务会回滚

    reply
    0
  • Cancelreply