spring注解事务使用总结
在使用spring的注解事务的时候,需要考虑到事务的传播行为、遇到什么类型的异常时,事务才起作用、事务方法之间的嵌套调用时,怎么样才生效等等诸多问题。网上搜到很多的主要还是一堆理论文字描述,我这里给出亲测的代码,是借助公司真实的系统来做测试。
系统之间调用图如下:

事务和异步处理都在server模块里面。
接口如下:
- /**
- * 测试事务行为接口
- *
- * @author plg
- *
- */
- public interface TestService {
- public void methodA();
- public void methodB();
- public void methodC();
- .
- .
- .
- }
/**
* 测试事务行为接口
*
* @author plg
*
*/
public interface TestService { public void methodA(); public void methodB(); public void methodC(); .
.
.
}
使用两个表:
- CREATE TABLE `mall_order_statistics` (
- `id` bigint(20) NOT NULL AUTO_INCREMENT,
- `shop_id` bigint(20) NOT NULL,
- `order_num` bigint(20) NOT NULL,
- `order_amount` bigint(20) NOT NULL,
- `avg_order_amount` bigint(20) NOT NULL,
- `pay_type` int(11) NOT NULL,
- `order_type` int(11) NOT NULL',
- `order_date` date NOT NULL,
- `create_time` datetime NOT NULL,
- PRIMARY KEY (`id`),
- KEY `idx_shop_id` (`shop_id`)
- ) ENGINE=InnoDB
- CREATE TABLE `mall_goods_ranking` (
- `id` bigint(20) NOT NULL AUTO_INCREMENT,
- `shop_id` bigint(20) NOT NULL,
- `order_date` date NOT NULL,
- `mall_goods_id` bigint(20) NOT NULL,
- `goods_name` varchar(20) NOT NULL,
- `sales_volume` bigint(20) NOT NULL,
- `sales_amount` bigint(20) NOT NULL,
- `create_time` datetime NOT NULL,
- PRIMARY KEY (`id`),
- KEY `idx_shop_id` (`shop_id`)
- ) ENGINE=InnoDB
CREATE TABLE `mall_order_statistics` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`shop_id` bigint(20) NOT NULL,
`order_num` bigint(20) NOT NULL,
`order_amount` bigint(20) NOT NULL,
`avg_order_amount` bigint(20) NOT NULL,
`pay_type` int(11) NOT NULL,
`order_type` int(11) NOT NULL',
`order_date` date NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_shop_id` (`shop_id`)
) ENGINE=InnoDB CREATE TABLE `mall_goods_ranking` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`shop_id` bigint(20) NOT NULL,
`order_date` date NOT NULL,
`mall_goods_id` bigint(20) NOT NULL,
`goods_name` varchar(20) NOT NULL,
`sales_volume` bigint(20) NOT NULL,
`sales_amount` bigint(20) NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_shop_id` (`shop_id`)
) ENGINE=InnoDB
1.事务与异常类型
这里用的是注解式事务@Transactional。
1.1 正常的处理
先来一个正常的处理,事先已把数据库表清空,代码调用如下:
- web端代码如下:
- try {
- testService.methodA();
- } catch (Exception e) {
- logger.error("========================= " + e);
- }
- server端代码如下:
- @Transactional
- @Override
- public void methodA() {
- MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
- mallGoodsRanking.setShopId(1L);
- mallGoodsRanking.setOrderDate(new Date());
- mallGoodsRanking.setMallGoodsId(1L);
- mallGoodsRanking.setGoodsName("测试");
- mallGoodsRanking.setSalesVolume(1L);
- mallGoodsRanking.setSalesAmount(1L);
- mallGoodsRanking.setCreateTime(new Date());
- mallGoodsRankingMapper.insert(mallGoodsRanking);
- MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
- mallOrderStatistics.setShopId(1L);
- mallOrderStatistics.setOrderNum(1L);
- mallOrderStatistics.setAvgOrderAmount(1L);
- mallOrderStatistics.setOrderAmount(1L);
- mallOrderStatistics.setPayType();
- mallOrderStatistics.setOrderType();
- mallOrderStatistics.setOrderDate(new Date());
- mallOrderStatistics.setCreateTime(new Date());
- mallOrderStatisticsMapper.insert(mallOrderStatistics);
- }
web端代码如下:
try {
testService.methodA();
} catch (Exception e) {
logger.error("========================= " + e);
} server端代码如下:
@Transactional
@Override
public void methodA() {
MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
mallGoodsRanking.setShopId(1L);
mallGoodsRanking.setOrderDate(new Date());
mallGoodsRanking.setMallGoodsId(1L);
mallGoodsRanking.setGoodsName("测试");
mallGoodsRanking.setSalesVolume(1L);
mallGoodsRanking.setSalesAmount(1L);
mallGoodsRanking.setCreateTime(new Date());
mallGoodsRankingMapper.insert(mallGoodsRanking); MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
mallOrderStatistics.setShopId(1L);
mallOrderStatistics.setOrderNum(1L);
mallOrderStatistics.setAvgOrderAmount(1L);
mallOrderStatistics.setOrderAmount(1L);
mallOrderStatistics.setPayType(1);
mallOrderStatistics.setOrderType(1);
mallOrderStatistics.setOrderDate(new Date());
mallOrderStatistics.setCreateTime(new Date());
mallOrderStatisticsMapper.insert(mallOrderStatistics);
}
执行结果:


1.2异常处理-不插入必填字段,抛出RuntimeException
- @Transactional
- @Override
- public void methodA() {
- MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
- mallGoodsRanking.setShopId(1L);
- mallGoodsRanking.setOrderDate(new Date());
- mallGoodsRanking.setMallGoodsId(1L);
- mallGoodsRanking.setGoodsName("测试");
- mallGoodsRanking.setSalesVolume(1L);
- mallGoodsRanking.setSalesAmount(1L);
- mallGoodsRanking.setCreateTime(new Date());
- mallGoodsRankingMapper.insert(mallGoodsRanking);
- MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
- // mallOrderStatistics.setShopId(1L);必填字段
- mallOrderStatistics.setOrderNum(1L);
- mallOrderStatistics.setAvgOrderAmount(1L);
- mallOrderStatistics.setOrderAmount(1L);
- mallOrderStatistics.setPayType();
- mallOrderStatistics.setOrderType();
- mallOrderStatistics.setOrderDate(new Date());
- mallOrderStatistics.setCreateTime(new Date());
- mallOrderStatisticsMapper.insert(mallOrderStatistics);
- }
@Transactional
@Override
public void methodA() {
MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
mallGoodsRanking.setShopId(1L);
mallGoodsRanking.setOrderDate(new Date());
mallGoodsRanking.setMallGoodsId(1L);
mallGoodsRanking.setGoodsName("测试");
mallGoodsRanking.setSalesVolume(1L);
mallGoodsRanking.setSalesAmount(1L);
mallGoodsRanking.setCreateTime(new Date());
mallGoodsRankingMapper.insert(mallGoodsRanking); MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
// mallOrderStatistics.setShopId(1L);必填字段
mallOrderStatistics.setOrderNum(1L);
mallOrderStatistics.setAvgOrderAmount(1L);
mallOrderStatistics.setOrderAmount(1L);
mallOrderStatistics.setPayType(1);
mallOrderStatistics.setOrderType(1);
mallOrderStatistics.setOrderDate(new Date());
mallOrderStatistics.setCreateTime(new Date());
mallOrderStatisticsMapper.insert(mallOrderStatistics);
}
如上面的代码,把第二条插入语句的一个必填字段注释掉,这样执行之后,抛出了异常:
- ; SQL []; Column 'shop_id' cannot be null; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'shop_id' cannot be null, dubbo version: 2.8., current host: 192.168.9.141
- org.springframework.dao.DataIntegrityViolationException:
; SQL []; Column 'shop_id' cannot be null; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'shop_id' cannot be null, dubbo version: 2.8.4, current host: 192.168.9.141
org.springframework.dao.DataIntegrityViolationException:
抛出了DataIntegrityViolationException类型的异常,这个异常是RuntimeException类型的异常,spring的@Transactional默认就是捕捉RuntimeException异常,遇到RuntimeException异常才会处理事务回滚。
既然抛出了RuntimeException异常,那数据库自然没有插入成功了。接下来演示抛出Exception异常,看事务能否生效。
1.3异常处理-不插入必填字段,抛出Exception
- @Transactional
- @Override
- public void methodA() throws Exception {
- try {
- MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
- mallGoodsRanking.setShopId(1L);
- mallGoodsRanking.setOrderDate(new Date());
- mallGoodsRanking.setMallGoodsId(1L);
- mallGoodsRanking.setGoodsName("测试");
- mallGoodsRanking.setSalesVolume(1L);
- mallGoodsRanking.setSalesAmount(1L);
- mallGoodsRanking.setCreateTime(new Date());
- mallGoodsRankingMapper.insert(mallGoodsRanking);
- MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
- // mallOrderStatistics.setShopId(1L);必填字段
- mallOrderStatistics.setOrderNum(1L);
- mallOrderStatistics.setAvgOrderAmount(1L);
- mallOrderStatistics.setOrderAmount(1L);
- mallOrderStatistics.setPayType();
- mallOrderStatistics.setOrderType();
- mallOrderStatistics.setOrderDate(new Date());
- mallOrderStatistics.setCreateTime(new Date());
- mallOrderStatisticsMapper.insert(mallOrderStatistics);
- } catch (Exception e) {
- logger.error(" ================== " + e);
- throw new Exception("异常");
- }
- }
@Transactional
@Override
public void methodA() throws Exception {
try {
MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
mallGoodsRanking.setShopId(1L);
mallGoodsRanking.setOrderDate(new Date());
mallGoodsRanking.setMallGoodsId(1L);
mallGoodsRanking.setGoodsName("测试");
mallGoodsRanking.setSalesVolume(1L);
mallGoodsRanking.setSalesAmount(1L);
mallGoodsRanking.setCreateTime(new Date());
mallGoodsRankingMapper.insert(mallGoodsRanking); MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
// mallOrderStatistics.setShopId(1L);必填字段
mallOrderStatistics.setOrderNum(1L);
mallOrderStatistics.setAvgOrderAmount(1L);
mallOrderStatistics.setOrderAmount(1L);
mallOrderStatistics.setPayType(1);
mallOrderStatistics.setOrderType(1);
mallOrderStatistics.setOrderDate(new Date());
mallOrderStatistics.setCreateTime(new Date());
mallOrderStatisticsMapper.insert(mallOrderStatistics);
} catch (Exception e) {
logger.error(" ================== " + e);
throw new Exception("异常");
}
}
捕捉异常后,然后 throw new Exception。执行后,抛出异常:
- java.lang.Exception: 异常
- at yunnex.saofu.mall.service.impl.TestServiceImpl.methodA(TestServiceImpl.java:)
- at yunnex.saofu.mall.service.impl.TestServiceImpl$$FastClassBySpringCGLIB$$8fcf06b.invoke(<generated>)
- at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:)
- at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:)
java.lang.Exception: 异常
at yunnex.saofu.mall.service.impl.TestServiceImpl.methodA(TestServiceImpl.java:55)
at yunnex.saofu.mall.service.impl.TestServiceImpl$$FastClassBySpringCGLIB$$8fcf06b.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)


看到了吗,第一条SQL还是插入成功了,第二条语句插入出错,抛出Exception异常,但是事务并没有回滚。 接下来测试一下@Transactional(rollbackFor=Exception.class)这种情况。
1.4异常处理-不插入必填字段,抛出Exception,@Transactional指定异常类型


数据库表没有插入数据。
2.事务方法嵌套使用
这里在引入一个表(mall_config),这个表原先是空的。
2.1事务方法调用私有方法,私有方法有数据库操作,私有方法抛出异常
- @Transactional
- @Override
- public void methodA() throws Exception {
- MallConfig mallConfig = new MallConfig();
- mallConfig.setCanFetch(true);
- mallConfig.setCanDeliver(true);
- mallConfigMapper.insert(mallConfig);
- this.insert();
- }
- private void insert() {
- MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
- mallGoodsRanking.setShopId(1L);
- mallGoodsRanking.setOrderDate(new Date());
- mallGoodsRanking.setMallGoodsId(1L);
- mallGoodsRanking.setGoodsName("测试");
- mallGoodsRanking.setSalesVolume(1L);
- mallGoodsRanking.setSalesAmount(1L);
- mallGoodsRanking.setCreateTime(new Date());
- mallGoodsRankingMapper.insert(mallGoodsRanking);
- MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
- // mallOrderStatistics.setShopId(1L);必填字段
- mallOrderStatistics.setOrderNum(1L);
- mallOrderStatistics.setAvgOrderAmount(1L);
- mallOrderStatistics.setOrderAmount(1L);
- mallOrderStatistics.setPayType();
- mallOrderStatistics.setOrderType();
- mallOrderStatistics.setOrderDate(new Date());
- mallOrderStatistics.setCreateTime(new Date());
- mallOrderStatisticsMapper.insert(mallOrderStatistics);//这里抛出异常
- }
@Transactional
@Override
public void methodA() throws Exception { MallConfig mallConfig = new MallConfig();
mallConfig.setCanFetch(true);
mallConfig.setCanDeliver(true);
mallConfigMapper.insert(mallConfig); this.insert();
} private void insert() {
MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
mallGoodsRanking.setShopId(1L);
mallGoodsRanking.setOrderDate(new Date());
mallGoodsRanking.setMallGoodsId(1L);
mallGoodsRanking.setGoodsName("测试");
mallGoodsRanking.setSalesVolume(1L);
mallGoodsRanking.setSalesAmount(1L);
mallGoodsRanking.setCreateTime(new Date());
mallGoodsRankingMapper.insert(mallGoodsRanking); MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
// mallOrderStatistics.setShopId(1L);必填字段
mallOrderStatistics.setOrderNum(1L);
mallOrderStatistics.setAvgOrderAmount(1L);
mallOrderStatistics.setOrderAmount(1L);
mallOrderStatistics.setPayType(1);
mallOrderStatistics.setOrderType(1);
mallOrderStatistics.setOrderDate(new Date());
mallOrderStatistics.setCreateTime(new Date());
mallOrderStatisticsMapper.insert(mallOrderStatistics);//这里抛出异常
}
执行结果:



数据没有插入,事务生效!在同一个类中,一个事务方法调用私用方法,私用方法里有对数据库的操作,私有方法里有异常(RuntimeException)产生,这种情况事务是起效果的。
2.2 事务方法调用私有方法,私有方法有数据库操作,事务方法抛出异常
- @Transactional
- @Override
- public void methodA() throws Exception {
- MallConfig mallConfig = new MallConfig();
- mallConfig.setCanFetch(true);
- mallConfig.setCanDeliver(true);
- mallConfigMapper.insert(mallConfig);
- this.insert();
- //第三部分
- MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
- // mallOrderStatistics.setShopId(1L);必填字段
- mallOrderStatistics.setOrderNum(1L);
- mallOrderStatistics.setAvgOrderAmount(1L);
- mallOrderStatistics.setOrderAmount(1L);
- mallOrderStatistics.setPayType();
- mallOrderStatistics.setOrderType();
- mallOrderStatistics.setOrderDate(new Date());
- mallOrderStatistics.setCreateTime(new Date());
- mallOrderStatisticsMapper.insert(mallOrderStatistics);
- }
- private void insert() {
- MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
- mallGoodsRanking.setShopId(1L);
- mallGoodsRanking.setOrderDate(new Date());
- mallGoodsRanking.setMallGoodsId(1L);
- mallGoodsRanking.setGoodsName("测试");
- mallGoodsRanking.setSalesVolume(1L);
- mallGoodsRanking.setSalesAmount(1L);
- mallGoodsRanking.setCreateTime(new Date());
- mallGoodsRankingMapper.insert(mallGoodsRanking);
- }
@Transactional
@Override
public void methodA() throws Exception { MallConfig mallConfig = new MallConfig();
mallConfig.setCanFetch(true);
mallConfig.setCanDeliver(true);
mallConfigMapper.insert(mallConfig); this.insert(); //第三部分
MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
// mallOrderStatistics.setShopId(1L);必填字段
mallOrderStatistics.setOrderNum(1L);
mallOrderStatistics.setAvgOrderAmount(1L);
mallOrderStatistics.setOrderAmount(1L);
mallOrderStatistics.setPayType(1);
mallOrderStatistics.setOrderType(1);
mallOrderStatistics.setOrderDate(new Date());
mallOrderStatistics.setCreateTime(new Date());
mallOrderStatisticsMapper.insert(mallOrderStatistics);
} private void insert() {
MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
mallGoodsRanking.setShopId(1L);
mallGoodsRanking.setOrderDate(new Date());
mallGoodsRanking.setMallGoodsId(1L);
mallGoodsRanking.setGoodsName("测试");
mallGoodsRanking.setSalesVolume(1L);
mallGoodsRanking.setSalesAmount(1L);
mallGoodsRanking.setCreateTime(new Date());
mallGoodsRankingMapper.insert(mallGoodsRanking);
}
看以上代码,只有第三部分那里抛出异常,执行结果和2.1一样如下。在同一个类里面,一个事务方法里调用私有方法,相当于代码都写在事务方法里。
2.3 接口方法调用私有方法,私有方法添加事务注解
- @Override
- public void methodA() throws Exception {
- MallConfig mallConfig = new MallConfig();
- mallConfig.setCanFetch(true);
- mallConfig.setCanDeliver(true);
- mallConfigMapper.insert(mallConfig);
- this.insert();
- }
- @Transactional
- private void insert() {
- MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
- mallGoodsRanking.setShopId(1L);
- mallGoodsRanking.setOrderDate(new Date());
- mallGoodsRanking.setMallGoodsId(1L);
- mallGoodsRanking.setGoodsName("测试");
- mallGoodsRanking.setSalesVolume(1L);
- mallGoodsRanking.setSalesAmount(1L);
- mallGoodsRanking.setCreateTime(new Date());
- mallGoodsRankingMapper.insert(mallGoodsRanking);
- MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
- // mallOrderStatistics.setShopId(1L);必填字段
- mallOrderStatistics.setOrderNum(1L);
- mallOrderStatistics.setAvgOrderAmount(1L);
- mallOrderStatistics.setOrderAmount(1L);
- mallOrderStatistics.setPayType();
- mallOrderStatistics.setOrderType();
- mallOrderStatistics.setOrderDate(new Date());
- mallOrderStatistics.setCreateTime(new Date());
- mallOrderStatisticsMapper.insert(mallOrderStatistics);
- }
@Override
public void methodA() throws Exception { MallConfig mallConfig = new MallConfig();
mallConfig.setCanFetch(true);
mallConfig.setCanDeliver(true);
mallConfigMapper.insert(mallConfig); this.insert();
} @Transactional
private void insert() {
MallGoodsRanking mallGoodsRanking = new MallGoodsRanking();
mallGoodsRanking.setShopId(1L);
mallGoodsRanking.setOrderDate(new Date());
mallGoodsRanking.setMallGoodsId(1L);
mallGoodsRanking.setGoodsName("测试");
mallGoodsRanking.setSalesVolume(1L);
mallGoodsRanking.setSalesAmount(1L);
mallGoodsRanking.setCreateTime(new Date());
mallGoodsRankingMapper.insert(mallGoodsRanking); MallOrderStatistics mallOrderStatistics = new MallOrderStatistics();
// mallOrderStatistics.setShopId(1L);必填字段
mallOrderStatistics.setOrderNum(1L);
mallOrderStatistics.setAvgOrderAmount(1L);
mallOrderStatistics.setOrderAmount(1L);
mallOrderStatistics.setPayType(1);
mallOrderStatistics.setOrderType(1);
mallOrderStatistics.setOrderDate(new Date());
mallOrderStatistics.setCreateTime(new Date());
mallOrderStatisticsMapper.insert(mallOrderStatistics);
}
执行结果如下:



出现异常后,前面两个表还是插入成功了。@Transactional放在private方法上是不起效果的,并且也不报错,spring官网也说明了这一点。实际上,像这种情况,内部调用带有事务注解的public方法,事务也不生效,也就是
- @Transactional
- public void insert() {
- 改成
- @Transactional
- private void insert() {
@Transactional
public void insert() { 改成 @Transactional
private void insert() {
具体原因请查看:http://blog.csdn.net/seelye/article/details/40144817。
方法内部调用带有事务注解的方法(无论是private还是public),事务是不生效的。
spring异步(@Async)处理也是一样,有时候在进行业务处理的过程,有些业务可以作为异步来处理,这时候就有一些同学就在同一类中新建一个方法,使用@Async注解,然后调用这个异步方法,其实这是不起作用的,一定要新建另外一个类,这个类新建公共方法,用@Async注解,然后调用才起到异步的作用。
spring注解事务使用总结的更多相关文章
- Spring注解(事务)
spring操作数据库 jdbc <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> & ...
- Spring -- 注解事务 以及 7个传播行为
注解事务: 1.开启注解事务配置: <!-- 事务管理器 --> <bean id="transactionManager" class="org.sp ...
- spring 注解事务
前提:在applicationContext.xml中配置<tx:annotation-driven transaction-manager="transactionManager&q ...
- spring注解事务管理
使用步骤: 步骤一.在spring配置文件中引入<tx:>命名空间<beans xmlns="http://www.springframework.org/schema/b ...
- 阶段3 2.Spring_10.Spring中事务控制_8 spring基于纯注解的声明式事务控制
新建项目 把之前项目src下的内容全部复制过来 pom.xml内复制过来 开始配置 新建一个config的包,然后再新建配置文件类SpringConfiguration @Configuration这 ...
- spring,mybatis事务管理配置与@Transactional注解使用[转]
spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是至关 ...
- 记录一次Spring boot 搭建框架连接Mysql数据库注解事务不回滚的故障
搭建了一个新框架,使用了spring boot 替换以简化原来繁杂的spring配置,使用Spring注解管理事务,持久层使用mybatis. 连接mysql数据库完成项目的过程中发现不支持事务,因为 ...
- Spring中注解事务方面的问题
我们可以在spring的配置文件beans.xml中对事务进行注解配置,这样在相应的类中就不用对事务进行管事,对于某个类,想单独交给spring来管理,那么就在相应的类上加入@Transactiona ...
- spring中注解事务认识
1.配置事务管理器 <!-- 设定transactionManager事务管理器 --> <bean id="txManager" class="org ...
随机推荐
- Swagger生成的接口需要权限验证的处理方法
通常开发API的时候需要对接口进行权限验证,而我们在使用Swagger生成接口文档界面的时候,直接调用需要权限验证的接口会提示"当前用户没有登陆" 为了解决此问题,我们需要更改一下 ...
- django-from
构建一个表单 这是一个非常简单的表单.实际应用中,一个表单可能包含几十上百个字段,其中大部分需要预填充,而且我们预料到用户将来回编辑-提交几次才能完成操作. 我们可能需要在表单提交之前,在浏览器端作一 ...
- cocos代码研究(21)Widget子类TextField学习笔记
基础理论 一个接受用户输入的widget. 输入文本的渲染基于TextFieldTTF. 如果你想用系统控制行为,请使用EditBox来替代.继承自 Widget. 代码实践 //与占位符有关void ...
- VS2010/MFC编程入门之十六(对话框:消息对话框)
前面几节鸡啄米讲了属性页对话框,我们可以根据所讲内容方便的建立自己的属性页对话框.本节讲解Windows系统中最常用最简单的一类对话框--消息对话框. 我们在使用Windows系统的过程中经常会见到消 ...
- 大数据领域两大最主流集群管理工具Ambari和Cloudera Manger
不多说,直接上干货! 目前啊,都知道,大数据集群管理方式分为手工方式(Apache hadoop)和工具方式(Ambari + hdp 和Cloudera Manger + CDH). 手工部署呢, ...
- Harbor 企业级 Docker Registry
HarBor项目:https://github.com/vmware/harbor 下载:https://github.com/vmware/harbor/releases 安装文档:https:// ...
- Applet再学习
ZLYD团队Apllet学习笔记 Applet再学习 Applet是什么? Applet又称为Java小应用程序,是能够嵌入到一个HTML页面中,并且可通过Web浏览器下载和执行的一种Java类 .A ...
- 关于函数strtok和strtok_r的使用要点和实现原理(一)【转】
本文转载自:http://astute11.blog.51cto.com/4404646/1334198 strtok函数的使用是一个老生常谈的问题了.该函数的作用很大,争议也很大.以下的表述可能与一 ...
- Learning Ansible with Vagrant
介绍 Vagrant介绍 Vagrant是一款构建虚拟开发环境的工具,Vagrant的使用依赖于VirtualBox,VMware等一些虚拟机,通过Vagrant能更加方便的管理虚拟机,同时还能够通过 ...
- BZOJ 4011 【HNOI2015】 落忆枫音
题目链接:落忆枫音 以下内容参考PoPoQQQ大爷的博客 首先我们先来考虑一下如果没有新加入的那条边,答案怎么算. 由于这是一个\(DAG\),所以我们给每个点随便选择一条入边,最后一定会构成一个树形 ...