当前位置: 首页 > news >正文

网站建设怎么样工作室如何建设网站内容

网站建设怎么样工作室,如何建设网站内容,wordpress简历,教育做的比较好的网站有哪些这篇文章#xff0c;会先讲述 Transactional 的 4 种不生效的 Case#xff0c;然后再通过源码解读#xff0c;分析 Transactional 的执行原理#xff0c;以及部分 Case 不生效的真正原因1 项目准备下面是 DB 数据和 DB 操作接口#xff1a;uidunameusex1张三女2陈恒男3楼仔…这篇文章会先讲述 Transactional 的 4 种不生效的 Case然后再通过源码解读分析 Transactional 的执行原理以及部分 Case 不生效的真正原因1 项目准备下面是 DB 数据和 DB 操作接口uidunameusex1张三女2陈恒男3楼仔男// 提供的接口 public interface UserDao {// select * from user_test where uid #{uid}public MyUser selectUserById(Integer uid);// update user_test set uname #{uname},usex #{usex} where uid #{uid}public int updateUser(MyUser user); }基础测试代码testSuccess() 是事务生效的情况Service public class UserController {Autowiredprivate UserDao userDao;public void update(Integer id) {MyUser user new MyUser();user.setUid(id);user.setUname(张三-testing);user.setUsex(女);userDao.updateUser(user);}public MyUser query(Integer id) {MyUser user userDao.selectUserById(id);return user;}// 正常情况Transactional(rollbackFor Exception.class)public void testSuccess() throws Exception {Integer id 1;MyUser user query(id);System.out.println(原记录: user);update(id);throw new Exception(事务生效);} }2 事务不生效的几种 Case主要讲解 4 种事务不生效的 Case类内部访问A 类的 a1 方法没有标注 Transactionala2 方法标注 Transactional在 a1 里面调用 a2私有方法将 Transactional 注解标注在非 public 方法上异常不匹配Transactional 未设置 rollbackFor 属性方法返回 Exception 等异常多线程主线程和子线程的调用线程抛出异常。2.1 类内部访问会导致事务不生效我们在类 UserController 中新增一个方法 testInteralCall()public void testInteralCall() throws Exception {testSuccess();throw new Exception(事务不生效类内部访问); }这里 testInteralCall() 没有标注 Transactional我们再看一下测试用例public static void main(String[] args) throws Exception {ApplicationContext applicationContext new ClassPathXmlApplicationContext(applicationContext.xml);UserController uc (UserController) applicationContext.getBean(userController);try {uc.testInteralCall();} finally {MyUser user uc.query(1);System.out.println(修改后的记录: user);} } // 输出 // 原记录:MyUser(uid1, uname张三, usex女) // 修改后的记录:MyUser(uid1, uname张三-testing, usex女)从上面的输出可以看到事务并没有回滚这个是什么原因呢因为 Transactional 的工作机制是基于 AOP 实现AOP 是使用动态代理实现的如果通过代理直接调用 testSuccess()通过 AOP 会前后进行增强增强的逻辑其实就是在 testSuccess() 的前后分别加上开启、提交事务的逻辑后面的源码会进行剖析。现在是通过 testInteralCall() 去调用 testSuccess()testSuccess() 前后不会进行任何增强操作也就是类内部调用不会通过代理方式访问。2.2 私有方法也会导致事务失效在私有方法上添加 Transactional 注解也不会生效Transactional(rollbackFor Exception.class) private void testPirvateMethod() throws Exception {Integer id 1;MyUser user query(id);System.out.println(原记录: user);update(id);throw new Exception(测试事务生效); }直接使用时下面这种场景不太容易出现因为 IDEA 会有提醒文案为: Methods annotated with Transactional must be overridable至于深层次的原理源码部分会进行解读。2.3 异常不匹配也会导致事务失效这里的 Transactional 没有设置 rollbackFor Exception.class 属性Transactional public void testExceptionNotMatch() throws Exception {Integer id 1;MyUser user query(id);System.out.println(原记录: user);update(id);throw new Exception(事务不生效异常不匹配); }public static void main(String[] args) throws Exception {ApplicationContext applicationContext new ClassPathXmlApplicationContext(applicationContext.xml);UserController uc (UserController) applicationContext.getBean(userController);try {uc.testSuccess();} finally {MyUser user uc.query(1);System.out.println(修改后的记录: user);} }// 输出 // 原记录:User[uid1,uname张三,usex女] // 修改后的记录:User[uid1,uname张三-test,usex女]Transactional 注解默认处理运行时异常即只有抛出运行时异常时才会触发事务回滚否则并不会回滚至于深层次的原理源码部分会进行解读。2.4 多线程也会导致事务失效下面给出两个不同的姿势一个是子线程抛异常主线程 ok一个是子线程 ok主线程抛异常。父线程抛出异常父线程抛出异常子线程不抛出异常public void testSuccess() throws Exception {Integer id 1;MyUser user query(id);System.out.println(原记录: user);update(id); } Transactional(rollbackFor Exception.class) public void testMultThread() throws Exception {new Thread(new Runnable() {SneakyThrowsOverridepublic void run() {testSuccess();}}).start();throw new Exception(测试事务不生效); }父线程抛出线程事务回滚因为子线程是独立存在和父线程不在同一个事务中所以子线程的修改并不会被回滚子线程抛出异常父线程不抛出异常子线程抛出异常public void testSuccess() throws Exception {Integer id 1;MyUser user query(id);System.out.println(原记录: user);update(id);throw new Exception(测试事务不生效); } Transactional(rollbackFor Exception.class) public void testMultThread() throws Exception {new Thread(new Runnable() {SneakyThrowsOverridepublic void run() {testSuccess();}}).start(); }由于子线程的异常不会被外部的线程捕获所以父线程不抛异常事务回滚没有生效。3 源码解读下面我们从源码的角度对 Transactional 的执行机制和事务不生效的原因进行解读。3.1 Transactional 执行机制我们只看最核心的逻辑代码中的 interceptorOrInterceptionAdvice 就是 TransactionInterceptor 的实例入参是 this 对象。红色方框有一段注释大致翻译为 “它是一个拦截器所以我们只需调用即可在构造此对象之前将静态地计算切入点。”this 是 ReflectiveMethodInvocation 对象成员对象包含 UserController 类、testSuccess() 方法、入参和代理对象等。进入 invoke() 方法后前方高能这里就是事务的核心逻辑包括判断事务是否开启、目标方法执行、事务回滚、事务提交。3.2 private 导致事务不生效原因在上面这幅图中第一个红框区域调用了方法 getTransactionAttribute()主要是为了获取 txAttr 变量它是用于读取 Transactional 的配置如果这个 txAttr null后面就不会走事务逻辑我们看一下这个变量的含义我们直接进入 getTransactionAttribute()重点关注获取事务配置的方法。前方高能这里就是 private 导致事务不生效的原因所在allowPublicMethodsOnly() 一直返回 false所以重点只关注 isPublic() 方法。下面通过位与计算判断是否为 Public对应的几类修饰符如下PUBLIC: 1PRIVATE: 2PROTECTED: 4看到这里是不是豁然开朗了有没有觉得很有意思呢~~3.3 异常不匹配原因我们继续回到事务的核心逻辑因为主方法抛出 Exception() 异常进入事务回滚的逻辑进入 rollbackOn() 方法判断该异常是否能进行回滚这个需要判断主方法抛出的 Exception() 异常是否在 Transactional 的配置中我们进入 getDepth() 看一下异常规则匹配逻辑因为我们对 Transactional 配置了 rollbackFor Exception.class所以能匹配成功示例中的 winner 不为 null所以会跳过下面的环节。但是当 winner null 时也就是没有设置 rollbackFor 属性时会走默认的异常捕获方式。前方高能这里就是异常不匹配原因的原因所在我们看一下默认的异常捕获方式是不是豁然开朗当没有设置 rollbackFor 属性时默认只对 RuntimeException 和 Error 的异常执行回滚。
http://www.hkea.cn/news/14424050/

相关文章:

  • wordpress 被黑后seo好wordpress主题
  • 只放一个图片做网站提升自己建设自己的网站
  • 视频库网站建设淘宝详情页psd模板免费
  • 柯桥建设局网站wordpress会员邀请系统
  • 类似电影天堂的网站 怎么做一个网站没有备案
  • 电 器建设网站目的及功能定位一级造价师停考最新消息
  • 四川省红鱼洞水库建设管理网站wordpress 删除小工具栏
  • 新潮狼网站建设网站建设备案需要材料
  • 网站如何做网页查询IT周末做网站违反制度么
  • 建设学校网站网页制作3个网页的网站图片
  • 网站建设去哪福州关键词快速排名
  • 网站建设副业怎么做晒鱼的网站
  • WordPress电影公司网站主题wordpress wp-config.php
  • 订阅号可以做微网站休闲农庄展示网站
  • 外贸汽车网站制作婚纱摄影类网站
  • 网站建设 应该付多少维护费呢电梯行业网站怎么做
  • 建官方网站的公司广州网站建设藤虎网络
  • 网站建设目标 优帮云wordpress当前分类热门调用
  • 当下 如何做网站赚钱房地产网站模板
  • 长沙雨花区建设局网站郑州妇科医院排行
  • 成都网站排名优化公司南昌住房建设局网站
  • 江门做网站费用潘家园做网站公司
  • 电竞网站开发需求报告网站备案资料 下载
  • 佛山智唯网站建设景区门户网站建设大数据分析
  • 长春做网站优化vs做网站开发
  • 响应式旅游网站模板下载做网站推广送什么
  • 公司做二手网站的用意产品展示型的网站功能有哪些
  • 怎么建设vip电影网站高校门户网站建设建议
  • 镇江当地网站做网站用php转html
  • 中英版网站怎么做制作一个公司网站的流程