spring事务

场景: 从A用户 转帐到B用户并进行日志记录,不管成功失败都进行日志操作,进行事务操作

1、AccountDao接口

@Repository
public interface AccountDao {
    @Update("update tbl_account set money = money - #{money} where name = #{name}")
    void outMoney(@Param("name") String name, @Param("money") Double money);

    @Update("update tbl_account set money = money + #{money} where name = #{name}")
    void inMoney(@Param("name") String name, @Param("money") Double money);

}

2、LogDao接口

public interface LogDao {

    @Insert("insert into tbl_log(info, createDate) values(#{info}, now())")
    void log(@Param("info") String info);
}

3、Account实体类

public class Account implements Serializable {
    private Integer id;
    private String name;
    private Double money;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }
    @Override
    public String toString(){
        return  "Account{" +
                "id="+id+
                ", name='"+name+ '\'' +
                ", money=" + money+"}";
    }
}

4、AccountService接口和实现类

public interface AccountService {

    /**
     * 转帐操作
     * @param out 传入方
     * @param in 转入方
     * @param money 金额
     */
    @Transactional
    public void transfer(String out, String in, Double money);

}


@Service
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountDao accountDao;

    @Autowired
    private LogService logService;


    public void transfer(String out, String in, Double money) {

       try {
           accountDao.outMoney(out, money);
           // 模拟异常操作
           int i = 1 / 0;
           accountDao.inMoney(in, money);
       } finally {
           logService.log(out, in, money);
       }


    }
}

5、LogService接口和实现类

public interface LogService {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    void log(String out, String in, Double money);
}
@Service
public class LogServiceImpl implements LogService {
    @Autowired
    private LogDao logDao;

    public void log(String out, String in, Double money) {
        logDao.log("转帐操作由"+out+"到"+ in +",金额:"+money);
    }
}
  • @Transactional 设置propagation为Propagation.REQUIRES_NEW  表明这个为新的事务和原来事务不合并

6、测试用例


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {

    @Autowired
    private AccountService accountService;
    
    @Test
    public void testTransfer(){
        accountService.transfer("Tom", "Jerry", 100D);
    }

}

7、补充

7.1、MybatisConfig配置类
public class MybatisConfig {
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
        SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
        ssfb.setTypeAliasesPackage("com.itheima.domain");
        ssfb.setDataSource(dataSource);
        return ssfb;
    }
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.itheima.dao");
        return msc;
    }

}
7.2、JdbcConfig配置类 
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;


    // step1: 定义一个方法获取要管理的对象
    // step2: 添加@Bean 表示当前方法的返回值是一个Bean
    @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 tm = new DataSourceTransactionManager();
        tm.setDataSource(dataSource);
        return tm;
    }

}
  • 事务管理还需要配置PlatformTransactionManager  管理器才能正常工作
7.3、 SpringConfig配置类
@Configuration
@ComponentScan({"com.itheima"})
@PropertySource("jdbc.properties")
@Import({JdbcConfig.class, MybatisConfig.class})
@EnableAspectJAutoProxy
@EnableTransactionManagement
public class SpringConfig {

}
  • @EnableAspectJAutoProxy  开启AOP切面编程
  • @EnableTransactionManagement 开启事务管理 

8、使用方法

public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        AccountService  accountService = ctx.getBean(AccountService.class);
        accountService.transfer("Tom","Jerry", 100D);

}

9、事务传播行为

传播属性事务管理员事务协调员
REQUIRED(默认)

开启T

加入T

新建T2

REQUIRES_NEW

开启T

新建T2

新建T2

SUPPORTS

 开启T

加入T

NOT_SUPPORTED

开启T

MANDATORY        

开启T

加入T

ERROR

NEVER

开启T

ERROR

NESTED设置savePoint,一旦事务回滚,事务将回滚到saovePoint处,交由客户响应提交/回滚

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值