spring事务-编程式事务

(1)spring事务管理 分为编程式和声明式
(2)区别:声明式事务,使用aop和JDK、CGLIB代理,通过代理方式来管理事务;而编程式事务使用模板设计模式和回调函数来管理事务。
(3)声明式事务:通常情况会使用基于@Transactional注解的声明式事务,只需在spring配置文件中加上相关的事务配置,通过在类名或者方法名上添加@Transactional注解来开启事务,操作极其简单,也能满足绝大多数业务需求。
(4)编程式事务:使用spring事务模板TransactionTemplate实现
既然声明式注解能满足大多数的业务需求,那么编程式事务是否无用武之地了呢?
下面看一个订单支付的例子:
@Transactional
public int payBill(String billId){ 
    Bill bill=billService.getById(billId);
    //调用第三方支付系统支付订单
    String flag=payService.invoke(url,bill); //返回支付状态
    Bill uptBill=new Bill();
    uptBill.setUuid(bill.getUuid);
    uptBill.setBillStatus(flag);
    billService.update(uptBill);
}
乍一看,上述支付代码很完美,会不会存在什么问题呢.......
如果有1000个用户同时在线支付,第三方支付系统吞吐量不够,每秒只能处理100个支付任务的情况下,会出现什么问题呢?
对于一个只设置了500个连接数的数据库会不会出问题呢?答案是肯定的,因为使用@Transactional声明事务,调用支付方法时,每个请求会单独占用一个数据库连接,直到支付完成后才会释放连接。
如果使用编程式事务,会怎么样呢?
@Autowired
private TransactionTemplate transactionTemplate; //声明事务模板
public int payBill(String billId){ 
    Bill bill=billService.getById(billId);
    transactionTemplate.execute(new TransactionCallback() {
                @Override
                public Object doInTransaction(TransactionStatus transactionStatus) {
                    Bill uptBill=new Bill();
                   uptBill.setUuid(bill.getUuid);
                   uptBill.setBillStatus(2); //正在支付
                   billService.update(uptBill);
                    return null;
                }
     });
    //调用第三方支付系统支付订单
    String flag=payService.invoke(url,bill); //返回支付状态
    transactionTemplate.execute(new TransactionCallback() {
                @Override
                public Object doInTransaction(TransactionStatus transactionStatus) {
                    Bill uptBill=new Bill();
                   uptBill.setUuid(bill.getUuid);
                   uptBill.setBillStatus(flag); 
                   billService.update(uptBill);
                    return null;
                }
     });
} 
  

如此,使用编程式事务,优雅的解决在调用第三方支付系统的耗时操作占用数据库连接的问题。

你可能感兴趣的:(spring相关,spring编程式事务)