事务的传播行为
一个事务方法调用另一个事务方法时,如何进行事务控制。是做为外部事务的整体控制?还是做为内部事务的部分控制?
在@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出错回滚了。并没有全部回滚