• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Spring事务失效场景原理及解决方案

java 搞代码 4年前 (2022-01-09) 40次浏览 已收录 0个评论

1.事务失效-自身调用(通过REQUIRES、REQUIRES_NEW传播属性):自身调用即调该类自己的方法。

同类OrderServiceImpl 中 doSomeThing()方法 不存在事务,该方法去调用本类中的存在事务注解的 insertAndUpdateOrderInfo() 方法。但是insertAndUpdateOrderInfo() 其实是无法保证预想的事务性。

示列验证:

OrderServiceImpl.insertAndUpdateOrderInfo方法中upateData(updateParam) 发生异常时,insertData(insertParam) 未发生回滚
说明:自身调用时候,无论是以下哪种传播属性均是无效的,因为自身调用时的子方法压根就不会被AOP 代理拦截到以下的这两种方式均经过验证,无法保证子方法事务的有效性

@Transactional(propagation = Propagation.REQUIRES)
@Transactional(propagation = Propagation.REQUIRES_NEW)

@Controller
@RequestMapping("/trans")
public class TransactionalController {

  @Autowired
  OrderService orderService;

  @RequestMapping("/test.do")
  @ResponseBody
  public void getIndex(HttpServletRequest request, HttpServletResponse response, Model model) {

    orderService.doSomeThing();

  }

}

@Service
public interface OrderService {

  /*
  *添加订单和修改其他订单信息
  * */
  public void doSomeThing();

}



@Service
public class OrderServiceImpl implements OrderService {
  @Autowired
  TransBusiness transBusiness;

  @Override
  public void doSomeThing() {

    insertAndUpdateOrderInfo();

  }

  @Transactional(propagation = Propagation.REQUIRED)
  public void insertAndUpdateOrderInfo(){
    Date date = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String updateTime = dateFormat.format(date);

    //步骤1:插入订单记录信息
    String[] insertParam = {"555555555", "977723233", updateTime, updateTime};
    transBusiness.insertData(insertParam);

    //步骤2:修改订单记录信息
    String[] updateParam = {"1111111111", updateTime, "1"};
    transBusiness.upateData(updateParam);
  }

}



@Service
public class TransBusiness {

  @Autowired
  JdbcTemplate dalClient;

  public void insertData(String[] param) {
    Map<String, Object> resultMap = new HashMap<>();
    String sql = "INSERT INTO test_order (`order_no`, `cust_no`,create_time,update_time) VALUES (?, ?,?,?)";

    int i = dalClient.update(sql, param);
    System.out.println("TransBusiness>>>insertData" + i);
    resultMap.put("插入的记录数", i);
  }

  public void upateData(String[] param) {
    Map<String, Object> resultMap = new HashMap<>();
    String sql<strong>本文来源gaodai#ma#com搞@@代~&码*网2</strong> = "update test_order set order_no =?,update_time=? ? where id= ?";

    int i = dalClient.update(sql, param);
    System.out.println("TransBusiness>>>upateData" + i);
    resultMap.put("修改的记录数", i);
  }

}

2.1自身调用事务失效解决方法1—在父方法中添加事务

通过doSomeThing()方法中添加事务性,可以解决1中事务自身调用失效的问题。

示列验证:

OrderServiceImpl.insertAndUpdateOrderInfo方法中当步骤1执行完成后,数据库中并不会存在该订单记录。当执行步骤2时发生了异常,整个事务发生了回滚。说明才方法解决了1自身调用事务失效的问题。

说明:此处的@Transactional等同于 @Transactional(propagation = Propagation.REQUIRED) 表示支持当前事务,如果没有事务就新建一个事务,这是常见的选择,也是spring默认的事务传播

@Override
  @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
  public void doSomeThing1() {
    insertAndUpdateOrderInfo();
  }

  public void insertAndUpdateOrderInfo(){
    Date date = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String updateTime = dateFormat.format(date);

    //步骤1:插入订单记录信息
    String[] insertParam = {"8888888888", "977723233", updateTime, updateTime};
    transBusiness.insertData(insertParam);

    //步骤2:修改订单记录信息
    String[] updateParam = {"1111111112", updateTime, "1"};
    transBusiness.upateData(updateParam);
  }

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Spring事务失效场景原理及解决方案
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址