spring事务和web请求


Spring事务失效的几种场景

1.检查时异常

@Transactional
public void transfer(int from,int to,int amount)  throws FileNotFoundException{
    int fromBalance=accountMapper.findBalanceBy(from);
    if(account-amount>=0){
        accountMapper.update(from,-1*amount);
        //这里可能会出现文件未找到的异常  如果throws或者try catch捕获  出现错误事务不会回滚
        new FileInputStream("aaa");
        accountMapper.update(to,amount);
    }
}

解决方法: @Transaction(rollbackFor = Expection.class)

2.异常没抛出

@Transactional(rollbackFor = Exception.class)
public void transfer(int from, int to,int amount){
try {
    int fromBalance=accountMapper.findBalanceBy(from);
    if (fromBalance - amount >= 0) {
        accountMapper.update(from, balance: -1 * amount);
        new FileInputstream( name: "aaa");//异常
        accountMapper.update(to,amount);
    }
}catch (FileNotFoundException e) {
    e.printstackTrace();
    throw new RuntimeException(e);//抛出去
    }
}
}

因为在执行的过程中,用到了代理。比如一个环绕通知,我们要执行的方法是一个内层的方法,内存方法出现异常如果不抛出,外层函数会认为程序正常执行了,所以不回滚。

3.切面配置过程
在使用mybatis时,首先调用事务环绕通知,然后调用自定义切面,然后调用方法。 出现异常都要把异常往外抛。 或者可以自定义执行的优先级顺序

4.非public方法

@Transaction加在public方法上

5.父子容器 子容器扫描的范围太大,把没加事务配置的service扫描进来了

解决:各扫各的 所有bean放在同一容器 springboot中一般不存在这个问题。

6.本类反法调用

没有经过代理调用 是通过this调用的

解决方法:自己注入自己 通过AopContext拿到代理

7.原子性失效

多线程并发时,我们用synchronized,但是如果我们把synchronized加在业务方法上,业务完成了,事务要提交的方法不属于synchronized的范围。因此事务可能未提交,其他线程开始执行了。所以把synchronized的范围包括到整个业务流程。 把synchronized加载调用的地方 等到任务完全结束,事务提交。

小结


session和cookie

session可以看做服务端的存储对象,cookie是存放在客户端浏览器的。

在web项目中,session是在访问tomcat服务器的时候创建的

//在这个时候创建
HttpSession session = request.getSession();

session创建后会保存在服务器内存,比如

//是放在服务端的     不会在用户浏览器那端可见
session.setAttribute("code","123456");

但是创建完后会有一个sessionId


客户端第一次请求session对象,服务器会为客户端创建一个session并通过特殊算法得到一个sessionId,用来标识session对象


/*
服务器第一次接收到请求时,开辟了一块Session空间(创建了Session对象),同时生成一个Session id,并通过响应头的Set-Cookie:“JSESSIONID=XXXXXXX”命令,向客户端发送要求设置cookie的响应; 客户端收到响应后,在本机客户端设置了一个JSESSIONID=XXXXXXX的cookie信息,该cookie的过期时间为浏览器会话结束;

接下来客户端每次向同一个网站发送请求时,请求头都会带上该cookie信息(包含Session id); 然后,服务器通过读取请求头中的Cookie信息,获取名称为JSESSIONID的值,得到此次请求的Session id;

​ 注意:服务器只会在客户端第一次请求响应的时候,在响应头上添加Set-Cookie:“JSESSIONID=XXXXXXX”信息,接下来在同一个会话的第二第三次响应头里,是不会添加Set- Cookie:“JSESSIONID=XXXXXXX”信息的; 而客户端是会在每次请求头的cookie中带上JSESSIONID信息;

HTTP Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的HTTP协议记录稳定的状态信息成为了可能。

Cookie 主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

Cookie 曾一度用于客户端数据的存储,因当时并没有其它合适的存储办法而作为唯一的存储手段,但现在随着现代浏览器开始支持各种各样的存储方式,Cookie 渐渐被淘汰。由于服务器指定 Cookie 后,浏览器的每次请求都会携带 Cookie 数据,会带来额外的性能开销(尤其是在移动环境下)


文章作者: 蛰伏
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 蛰伏 !
  目录