5.transaction(事务)
作用:在数据层或业务层保障同一系列的数据库操作同成功或同失败;
1.在业务层接口上添加Spring事务管理
@Transactional
void transfer(String out,String in,double money);
2.设定事务管理器(在JdbcConfig中)
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager d = new DataSourceTransactionManager();
d.setDataSource(dataSource);
return d;
}
3.开启注解事务驱动
@Configuration
@ComponentScan({"org.example"})
@PropertySource({"db.properties"})
@Import({JdbcConfig.class,MyBatisConfig.class})
@EnableAspectJAutoProxy
@EnableTransactionManagement
public class SpringConfig {
}
4.角色:
事务管理员(Spring开启的事务),事务协调员(加入Spring事务)
有些异常可能不参与事务的回滚,需要手动加,例如:
@Transactional(rollbackFor={IOException.class})
5.案例:转账业务追加日志
实现效果:无论转账是否成功,均进行转账操作的日志留痕;
public interface LogService {
@Transactional
void log(String out,String in,double money);
}
public interface LogDao {
@Insert("insert into log(info,createdata)values(#{info},now())")
void log(String info);
}
@Service
public class LogImpl implements LogService {
@Autowired
private LogDao dao;
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void log(String out, String in, double money) {
dao.log("转账操作由"+out+"到"+in+",金额:"+money);
}
}
@Transactional
public interface BankService {
@Transactional
void transfer(String out,String in,double money);
}
@Service
public class BankImpl implements BankService {
@Autowired
private BankDao dao;
@Autowired
private LogService log;
@Override
public void transfer(String out, String in, double money) {
try {
dao.inMoney(in, money);
int i = 1/0;
dao.outMoney(out, money);
}finally {
log.log(out,in,money);
}
}
}
public interface BankDao {
@Update("update userinfo set money=money+#{money} where name=#{name}")
void inMoney(@Param("name") String name,@Param("money") double money);
@Update("update userinfo set money=money-#{money} where name= #{name}")
void outMoney(@Param("name") String name,@Param("money") double money);
}
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager d = new DataSourceTransactionManager();
d.setDataSource(dataSource);
return d;
}
}
public class MyBatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setTypeAliasesPackage("org.example.entity");
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer (){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("org.example.dao");
return mapperScannerConfigurer;
}
}
@Configuration
@ComponentScan({"org.example"})
@PropertySource({"db.properties"})
@Import({JdbcConfig.class,MyBatisConfig.class})
@EnableAspectJAutoProxy
@EnableTransactionManagement
public class SpringConfig {
}
|