Spring事务的传播行为

事务的传播行为

一个事务方法调用另一个事务方法时,如何进行事务控制。是做为外部事务的整体控制?还是做为内部事务的部分控制?
在@Transactional注解中,使用propagation属性指导事务的传播行为。

required -- 有事务就行(事务默认传播行为)
@Transactional(propagation=Propagation.REQUIRED)

required new -- 使用自己的事务,外面调用的方法的事务被挂起。
@Transactional(propagation=Propagation.REQUIRES_NEW)

事务的隔离级别:

脏读,不可重复读,幻读
在@Transactional注解中,使用isolation属性指定事务的隔离级别。最常用的是Read_Commit

实例:

xml

 

package com.itnba.maya.daoimp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.itnba.maya.dao.IInfoService;
@Component
public class TestAll {
    @Autowired
    private IInfoService testall;
    @Transactional//这是最外层的事务,里面有一个错的全部都回滚
    public void delete(){
        testall.delete("p003");
        testall.delete("p005");
        
    }
}

接口

package com.itnba.maya.dao;

public interface IInfoService {
    public void delete(String code);

}

 

 

 

package com.itnba.maya.daoimp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.itnba.maya.dao.IInfoDao;
import com.itnba.maya.dao.IInfoService;
import com.itnba.maya.dao.IWorkDao;
@Repository//自动扫描注解
public class InfoService implements IInfoService {
    @Autowired//ByName自动装配
    private IInfoDao infoDao; 
    @Autowired//ByName自动装配
    private IWorkDao workdao;
    @Transactional(propagation=Propagation.REQUIRES_NEW)//使用自己的事务,外面调用的方法的事务被挂起。也就是说只回滚错误的,并不会全部回滚

    public void delete(String code) {
        
        infoDao.delete(code);
        workdao.deleteInfocode(code);
        
    }

}
package com.itnba.maya.daoimp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.itnba.maya.dao.IInfoDao;
@Repository
public class InfoDao implements IInfoDao {
    @Autowired
    private JdbcTemplate j;
    @Override
    public void delete(String code) {
        // TODO 自动生成的方法存根
        if(code.equals("p005")){
            int i=5/0;//故意写个错误
        }
        String sql="delete from info where code=?";
        j.update(sql,code);
    }

}
package com.itnba.maya.daoimp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.itnba.maya.dao.IWorkDao;
@Repository
public class WorkDao implements IWorkDao {
    @Autowired
    private JdbcTemplate j;
    @Override
    public void deleteInfocode(String code) {
    
        String sql="delete from work where infocode=?";
        j.update(sql,code);
    }

}

这样就是当p003的时候会执行,是005的是时候回滚,用main函数试一下

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.itnba.maya.dao.IInfoDao;
import com.itnba.maya.dao.IInfoService;
import com.itnba.maya.dao.IWorkDao;

public class Test {
    private static ApplicationContext context=null;
    private static IInfoDao infodao=null;
    private static IWorkDao workdao=null;
    private static IInfoService infoservice=null;
    private static TestAll testall=null;
    
    
    static{
        context=new ClassPathXmlApplicationContext("beans.xml");
        infodao =(IInfoDao)context.getBean("infoDao");
        workdao=(IWorkDao)context.getBean("workDao");
        infoservice=(IInfoService) context.getBean("infoService");
        testall=(TestAll) context.getBean("testAll");
    }
    public static void main(String[] args) {
        testall.delete();

    }
}

结果:只删了p003,而p005出错回滚了。并没有全部回滚

 

posted @ 2017-04-04 13:15  滥好人  阅读(443)  评论(0编辑  收藏  举报