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

永州网站建设多少钱微信搜一搜seo优化

永州网站建设多少钱,微信搜一搜seo优化,如何做网站app,做调查的网站推荐Spring中事务的操作分为两类:(1)编程式事务 – 手动写代码操作事务(2)声明式事务 – 利用注解开启事务和提交事务 1. 编程式事务 准备Controller RestController RequestMapping("/user") public class UserInfoController {Autowiredprivate UserInfoService use…

Spring中事务的操作分为两类:
(1)编程式事务 – 手动写代码操作事务
(2)声明式事务 – 利用注解开启事务和提交事务

1. 编程式事务

准备Controller


@RestController
@RequestMapping("/user")
public class UserInfoController {@Autowiredprivate UserInfoService userInfoService;@RequestMapping("addUser")public String addUser(UserInfo userInfo) {userInfoService.insert(userInfo);return "SUCCESS";}
}

Spring Boot内置了两个对象
DataSourceTransactionManager事务管理器,用来开始事务,提交或回滚事务
TransactionDefinition是事务的属性,在开启事务的时候需要将TransactionDefinition传递进去从而获得一个事务TransactionStatus

先来看没有事务的执行结果:
访问后:
image.png

如果设置了事务:

@RestController
@RequestMapping("/user")
@Slf4j
public class UserInfoController {//事务管理器@Autowiredprivate DataSourceTransactionManager transactionManager;//定义事务属性@Autowiredprivate TransactionDefinition transactionDefinition;@Autowiredprivate UserInfoService userInfoService;@RequestMapping("/addUser")public String addUser(UserInfo userInfo) {log.info("addUser:{}",userInfo);//开启事务TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);userInfoService.insert(userInfo);//事务提交transactionManager.commit(transactionStatus);return "SUCCESS";}
}

执行结果:
image.png
观察数据库,发现两条数据都有插入:
image.png

如果我们设置了回滚

@RequestMapping("/addUser")
public String addUser(UserInfo userInfo) {
log.info("addUser:{}",userInfo);
//开启事务
TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);userInfoService.insert(userInfo);//事务提交
transactionManager.rollback(transactionStatus);
return "SUCCESS";
}

image.png
对比发现,如果是成功提交,输出的日志是
image.png
如果回滚了,输出的日志是没有这一条信息的,并且数据库也不会更新

但是如果此时我们再次提交事务:
image.png
查看数据库的数据:
image.png
中间空着的id为17的数据就是我们刚刚回滚的操作

2. Spring声明式事务@Transactional

声明式事务的实现需要两步:

2.1 添加依赖

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency> 

2.2 添加@Transactional注解

在需要添加事务的地方加上@Transactional注解即可,无需手动开启事务和提交事务
如果中途发生了没有处理的异常会回滚事务

正常情况:

@RestController
@RequestMapping("/user1")
@Slf4j
public class UserInfoController1 {@Autowiredprivate UserInfoService userInfoService;@Transactional@RequestMapping("/addUser1")public String addUser(UserInfo userInfo) {log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);return "SUCCESS";}
}

image.png

异常情况:

@Transactional
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) {
log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);
int a = 10/0;//出现未处理的异常
return "SUCCESS";
}

image.png
此时会自动回滚,没有提交
但是如果异常在方法内被处理了,就会提交事务

@Transactional
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) {
log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);
try {int a = 10/0;
} catch (Exception e) {e.printStackTrace();
}
return "SUCCESS";
}

image.png
我们可以在catch里面手动进行回滚事务:

@Transactional
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) {
log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);
try {int a = 10/0;
} catch (Exception e) {e.printStackTrace();TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return "SUCCESS";
}

再次访问:不会提交
image.png

注意:@**Transactional**** **注解可以用来修饰方法或类:

  • 修饰方法时,只有修饰public方法时才生效(修饰其他方法时不会报错,但是不会生效)
  • 修饰类时,类中所有的public方法都会生效
@Transactional
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) {
log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);
try {int a = 10/0;
} catch (Exception e) {e.printStackTrace();TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return "SUCCESS";
}

2.3 @Transactional详解

@Transactional有三个重要的属性:

2.3.1 rollbackFor

@Transactional默认只是在遇到运行时异常以及Error时才会回滚,非运行时异常不会回滚

@Transactional
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) throws IOException {log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);if (true) {throw new IOException();}return "SUCCESS";
}

访问:
image.png
事务是会提交的
如果我们需要对所有的异常都回滚,需要配置@Transactional注解当中的rollbackFor属性指定出现何种异常时事务进行回滚

@Transactional(rollbackFor = Exception.class)
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) throws IOException {log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);if (true) {throw new IOException();}return "SUCCESS";
}

再次访问:事务不会提交
image.png

2.3.2 事务隔离级别

MySQL事务隔离级别

SQL定义了四种隔离级别:

  1. 读未提交:该隔离级别的事务可以看到其他事务中未提交的数据

其他事务未提交的数据可能会发生回滚,但是该隔离级别的事务可以读到,我们吧该级别读到的数据称为脏数据,这个问题称为脏读

  1. 读已提交:该隔离级别的事务能读取到已经提交事务的数据

该隔离级别不会有脏读的问题,但是由于在事务的执行过程中可以读取到其他事务提交的结果,所以在不同时间相同的sql查询可能会读到不同的结果,这种现象叫做不可重复读

  1. 可重复读:事务不会读到其他事务对已有数据的修改,即使其他事务已经提交,也可以确保

在同一事务多次查询的结果是一致的,但是其他事务新插入的数据,是可以感知到的,这也就引发了幻读问题.可重复读是MySQL默认的事务隔离级别

  1. 串行化:序列化,事务最高的隔离级别,他会强制事务排序,使之不会产生冲突,从而解决

脏读,不可重复读和幻读问题,但是执行效率低,使用场景不多

Spring事务隔离级别

Spring中事务隔离级别有5种

  1. Isolatio.DEFAULT以连接的数据库的事务隔离级别为主
  2. Isolation.READ_UNCOMMITTED:读未提交,对应SQL标准中的读未提交
  3. Isolation.READ_COMMITTED: 读已提交,对应SQL标准中的读已提交
  4. Isolation.REPEATABLE_READ:可重复读.对应SQL标准中的可重复读
  5. Isolation.SERIALIZABLE:串行化,对应SQL标准中的串行化

image.png
Spring中事务隔离级别可以通过@Transactional中的Isolation属性进行设置

@Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_UNCOMMITTED)
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) throws IOException {log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);return "SUCCESS";
}

2.3.3 事务传播机制

事务传播机制就是,多个事务之间存在调用关系时,事务是如何在这些方法间进行传播的
比如A方法调用B方法,A执行时,会开启一个事务,B本身也存在一个事务,此时B的事务是加入A的事务,还是创建一个新的事务
这就涉及到了事务传播机制
@Transactional注解支持事务传播机制的设置,通过propagation属性来指定传播行为

  1. Propagation.REQUIRED:默认的事务传播级别.表示如果当前存在事务,则加入该事务.如果当前没有事务,则创建一个事务
  2. Propagation.SUPPORTS:如果当前存在事务,则加入事务;如果当前没有存在事务,则以非事务的方式继续进行
  3. Propagation.MANDATORY:强制性,如果当前存在事务,则加入事务,如果当前没有事务,则抛出异常
  4. Propagation.REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起,也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW修饰的内部方法都会新开自己的事务,且开启的事务相互独立,互不干扰
  5. Propagation.NOT_SUPPORTED以非事务的方式运行,如果当前存在事务,则把当前的事务挂起
  6. Propagation.NEVER以非事务的方式运行,如果当前存在事务,则抛出异常
  7. Propagation.NESTED如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果没有事务,则该取值等价于Propagation.REQUIRED

我们通过代码来演示一下区别:
(1)REQUIRED
image.png
此时由于是REQUIRED,那么三个方法针对的是同一个事务,只要其中有一个出现异常,都会回滚
image.png
image.png
(2)REQUIRES_NEW
image.png
在这种条件下,事务之间是独立的,因此互不影响
image.png
此时user的事务提交了,但是log的事务回滚了

(3)NEVER
image.png
如果存在事务,那就抛出异常
image.png

(4) NESTED
我们先来看看REQUIRED如果方法都执行成功的情况下:
image.png
如果是NESTED,方法都执行成功的情况下:
image.png
image.png
可以发现是等价的,同样是只是开启了一次事务

如果发生了异常
对于REQUIRED方法:

如果是NESTED
image.png
事务都是全部回滚
看似两种好像都是一样的,实际上存在差别
REQUIRED是加入,而NESTED是嵌套
我们通过以下代码就能很好的看出两种的区别:
image.png
对于NESTEDE:
image.png
image.png
但是对于REQUIRED:
image.png
数据库两个表都没有新增数据
可以注意到,在REQUIRED里面,由于是同一个事务,因此不能部分回滚

http://www.ds6.com.cn/news/7931.html

相关文章:

  • 两个女孩子怎么做网站热门搜索关键词
  • 外国人做汉字网站网站推广方案范例
  • 网站权限现在最好的免费的建站平台
  • 建设网站的用途百度竞价代运营外包
  • 怎么做交易平台网站亚马逊跨境电商
  • 中山网站建设模板网络公司最近一周的重大新闻
  • 人力资源公司网站模板下载产品营销
  • 网站设计技巧全网营销推广方式
  • 农家乐网站 建设国内网站排名
  • 做网站哪里最好什么网站做推广比较好
  • 北京做网站好的必应搜索引擎网址
  • 新网站怎么做谷歌推广呢搜索引擎优化核心
  • 网站怎么做能赚钱销售渠道及方式
  • 最新收藏五个以上的本地域名seo推广优化的方法
  • 做网站的软件著作权关键词可以分为哪三类
  • 企业需求做网站在哪儿交易泰安百度推广代理商
  • 做网站用什么电脑好seo虚拟外链
  • 防伪码查询网站怎么做的企业推广网站
  • 做网站需要的程序旺道seo软件
  • 哪里做网站做的好麒麟seo软件
  • 还有做网站的必要吗杭州网络
  • 三网合一网站建设百科怎么把网站排名优化
  • 个人网站怎么做推广怎样推广自己的产品
  • 湖州网站建设哪家公司好百家号权重查询
  • 移动互联网站建设seo自学网app
  • vps里面网站php页面无法打开搜索引擎调词工具哪个好
  • 武汉网上商城网站建设广告联盟推广
  • 10大设计师网站百度直播平台
  • 日本做灯具公司网站自动收录
  • 可以做设计赚钱的网站seo优化自动点击软件