示例代码地址:https://gitee.com/gtnotgod/Springcloud-alibaba.git

更详细参考Gitee完整的项目:https://gitee.com/gtnotgod/Springcloud-alibaba.git

官网下载Nacos

https://nacos.io/zh-cn/index.html

压缩包解压:

配置Nacos:**/nacos/conf/application.properties

#*************** Spring Boot Related Configurations ***************#
### Default web context path:
server.servlet.contextPath=/nacos
### Include message field
server.error.include-message=ALWAYS
### Default web server port:
server.port=8848
### Metrics for elastic search
management.metrics.export.elastic.enabled=false
#management.metrics.export.elastic.host=http://localhost:9200
#*************** Access Log Related Configurations ***************#
### If turn on the access log:
server.tomcat.accesslog.enabled=true
### The access log pattern:
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i
### The directory of access log:
server.tomcat.basedir=file:.
#*************** Access Control Related Configurations ***************#
### If enable spring security, this option is deprecated in 1.2.0:
#spring.security.enabled=false
### The ignore urls of auth
nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
### The auth system to use, currently only 'nacos' and 'ldap' is supported:
nacos.core.auth.system.type=nacos
### If turn on auth system: ### 开启鉴权
nacos.core.auth.enabled=true
### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
nacos.core.auth.caching.enabled=true
### 关闭使用user-agent判断服务端请求并放行鉴权的功能
nacos.core.auth.enable.userAgentAuthWhite=false
### Since 1.4.1, worked when nacos.core.auth.enabled=true and nacos.core.auth.enable.userAgentAuthWhite=false.
### The two properties is the white list for auth and used by identity the request from other server.
nacos.core.auth.server.identity.key=nacos
nacos.core.auth.server.identity.value=nacos
### The token expiration in seconds:
nacos.core.auth.plugin.nacos.token.cache.enable=false
nacos.core.auth.plugin.nacos.token.expire.seconds=18000
### The default token (Base64 String):
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
### 2.1.0 版本后
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
nacos.istio.mcp.server.enabled=false

启动Nacos:进入目录/nacos/bin

startup.cmd -m standalone

启动完成,

访问: http://localhost:8848/nacos

访问:账号密码 nacos nacos

官网下载Seata

https://seata.io/zh-cn/index.html

本地解压

初始化数据库:进入seata\script\server\db

配置Naco配置中心和Nacos注册中心,Mysql数据库

seata\conf\application.yml


server:
port: 7091 spring:
application:
name: seata-server logging:
config: classpath:logback-spring.xml
file:
path: ${user.home}/logs/seata
extend:
logstash-appender:
destination: 127.0.0.1:4560
kafka-appender:
bootstrap-servers: 127.0.0.1:9092
topic: logback_to_logstash console:
user:
username: seata
password: seata seata:
service:
vgroup-mapping:
my-seata-group: default
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group : "SEATA_GROUP"
namespace: "70180ace-e644-4a10-b590-e6a6003b1bbe"
username: "nacos"
password: "nacos"
data-id: seataServer.properties
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group : "SEATA_GROUP"
namespace: "70180ace-e644-4a10-b590-e6a6003b1bbe"
username: "nacos"
password: "nacos"
store:
# support: file 、 db 、 redis
# 注意数据库版本为5.7.26 , 使用8.0.12时报错Could not retrieve transation read-only status server
mode: db
db:
datasource: druid
db-type: mysql
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/seata1.6.1?rewriteBatchedStatements=true&useUnicode=true
user: root
password: root
min-conn: 5
max-conn: 100
global-table: global_table
branch-table: branch_table
lock-table: lock_table
distributed-lock-table: distributed_lock
query-limit: 100
max-wait: 5000
# server:
# service-port: 8091 #If not configured, the default is '${server.port} + 1000'
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login

启动Seata ,双击



出现这个

Nacos服务列表



出现这个

Nacos控制台配置 tx-service-group



出现这个

springcloud项目集成Nacos和Seata

项目公共依赖:

公共依赖lombok、web、MySQL、mybatisplus、dynamicDataSource、knife4j、bootstrap、loadbalancer

 <properties>
<mybatis-plus.version>3.5.1</mybatis-plus.version>
<com.alibaba.druid.version>1.2.11</com.alibaba.druid.version>
<nacos-client.version>2.0.4</nacos-client.version>
<fastJson-version>2.0.18</fastJson-version>
</properties> <dependencies>
<!--lombok-实体类简化依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--web项目驱动-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!--Mysql数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${com.alibaba.druid.version}</version>
</dependency>
<!--Mybatis ORM相关依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!--Mybatis-plus 代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.verison}</version>
</dependency>
<!-- mybatis-plus默认模板引擎-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.engine.version}</version>
</dependency>
<!--Mybatis-plus 多数据源-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${mybatisplus.verison}</version>
</dependency>
<!--Swagger2-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!-- bootstrap最高级启动配置读取 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--新版的移除了Ribbon的负载策略,所需改用新版的loadbalancer-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastJson-version}</version>
</dependency>
</dependencies>

项目一 AppUserManage :10085

依赖

 <dependencies>

        <!--分布式事务解决方案(阿里巴巴seata)-->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>${seata.version}</version>
</dependency> <!--If your project base on `Spring Boot`, you can directly use the following dependencies-->
<!--Notice: `seata-spring-boot-starter` has included `seata-all` dependency-->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>${seata.version}</version>
</dependency>
<!--分布式事务解决方案(阿里巴巴seata)-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
</exclusion>
</exclusions>
</dependency> <!--微服务项目公共依赖lombok、web、MySQL、mybatisplus、dynamicDataSource、knife4j、bootstrap、loadbalancer-->
<dependency>
<groupId>com.gton</groupId>
<artifactId>common-dependce</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--nacos服务发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--Nacos配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--Springcloud微服务启动-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<!--全局最高配置加载-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.1</version>
</dependency> <!--Dubbo的RPC框架-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<!--Springboot的dubbo适配-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!--Dubbo适配naocs-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
</dependency>
<!--nacos2的客户端-->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--Redis使用公共依赖-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
</dependencies>

核心配置 bootstrap.yml

# Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html
# Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可
# spring.cloud.nacos.config.namespace=
spring:
application:
#服务自动发现并注册,不需要name
name: user-manager
cloud:
alibaba:
seata:
tx-service-group: my-seata-group
nacos:
discovery:
server-addr: ${spring.cloud.nacos.server-addr} # 设置配置中心服务端地址
group: AlibabaCloud
username: nacos
password: nacos
namespace: 70180ace-e644-4a10-b590-e6a6003b1bbe
config:
username: ${spring.cloud.nacos.discovery.username} # Nacos认证信息用户名
password: ${spring.cloud.nacos.discovery.password} # Nacos认证信息密码
context-path: /nacos # Nacos根路径
enabled: true
server-addr: ${spring.cloud.nacos.server-addr}
group: ${spring.cloud.nacos.discovery.group}
namespace: 70180ace-e644-4a10-b590-e6a6003b1bbe
file-extension: properties
server-addr: 127.0.0.1:8848 # 设置配置中心服务端地址
seata:
enabled: true
application-id: ${spring.application.name}
# 客户端和服务端在同一个事务组; Seata 事务组编号,用于 TC 集群名, 一定要和 config.tx(nacos) 中配置的相同
tx-service-group: my-seata-group
# 自动数据源代理
enable-auto-data-source-proxy: true
# 数据源代理模式(分布式事务方案)
data-source-proxy-mode: AT
# 事务群组,配置项值为TC集群名,需要与服务端保持一致
service:
vgroup-mapping:
my-seata-group: default
#整合nacos配置中心
config:
type: nacos
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
group: SEATA_GROUP
namespace: 70180ace-e644-4a10-b590-e6a6003b1bbe
data-id: seataServer.properties
username: nacos
password: nacos
#整合nacos注册中心
registry:
type: nacos
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
group: SEATA_GROUP
namespace: 70180ace-e644-4a10-b590-e6a6003b1bbe
# 默认TC集群名
cluster: default
# 服务名,与服务端中registry.conf配置要一致
application: seata-server
username: nacos
password: nacos
dubbo:
# 配置元数据中心
metadata-report:
address: nacos://127.0.0.1:8848?username=${dubbo.metadata-report.username}&password=${dubbo.metadata-report.password}
username: nacos
password: nacos
parameters:
namespace: 70180ace-e644-4a10-b590-e6a6003b1bbe
retry-times: 30 #重试次数,默认100
cycle-report: false #关闭定时刷新
application:
name: dubbo-consumer
# 禁用QOS同一台机器可能会有端口冲突现象
qos-enable: false
qos-accept-foreign-ip: false
service-discovery:
migration: FORCE_APPLICATION # FORCE_APPLICATION,只消费应用级地址,如无地址则报错,单订阅 3.x 地址
protocol:
name: dubbo
port: -1
scan:
base-packages: com.gton.router.impl
cloud:
subscribed-services: consumer
registry:
address: nacos://127.0.0.1:8848?username=${dubbo.metadata-report.username}&password=${dubbo.metadata-report.password}
parameters:
namespace: 70180ace-e644-4a10-b590-e6a6003b1bbe
consumer:
check: false

启动类

package com.gton;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /**
* @description: APP-Usermanage服务
* @author: GuoTong
* @createTime: 2022-09-24 13:48
* @since JDK 1.8 OR 11
**/
@SpringBootApplication
@EnableDiscoveryClient //服务发现客户端
public class AppUserManage { public static void main(String[] args) {
/**
* Description:
* 数据库连接全部使用mybatis-plus安全加密,加密密匙:
* 在启动参数 (Program arguments) --mpw.key=4b57e89bac82a797
*/
try {
SpringApplication.run(AppUserManage.class, args);
} catch (Exception e) {
e.printStackTrace();
}
}
}

测试接口 包含:Dubbo的RPC调用,Seata分布式事务的测试


/**
* @description:
* @author: GuoTong
* @createTime: 2022-09-24 14:37
* @since JDK 1.8 OR 11
**/
@RestController
@Api(tags = "测试接口")
@SwaggerScanClass
@Slf4j
public class HelloController { @Value("${user.name:zhangsan}")
private String name; @Value("${user.age:100}")
private int age; @Autowired
private GpLoginService gpLoginService; /**
* Description: Dubbo RPC调用服务方
*
* @author: GuoTong
* @date: 2022-09-24 17:50:08
* @param null
* @return:
*/
@Autowired
private DubboRPCThirdSysRouterService dubboRPCThirdSysRouterService; @RequestMapping(value = "/hello", method = RequestMethod.GET)
@ApiOperation(value = "hello", notes = "json格式")
@ApiResponse(code = 200, message = "返回的是json格式", response = Resp.class)
public Resp hello() {
Map<String, Object> data = new HashMap<>();
data.put("call-UrI", "hello");
data.put("port", "8089");
data.put("service-Name", "cloud-nacos");
data.put("server-type", "nacos");
data.put("server-addr", "127.0.0.1:8848");
data.put("swagger-Uri", "doc.html");
data.put("nacos-properties-name", name);
data.put("nacos-properties-age", age);
return Resp.Ok(data);
} @RequestMapping(value = "/dubbo_get_thirdsysrouter", method = RequestMethod.GET)
@ApiOperation(value = "usermanager服务调用thirdsysrouter", notes = "json格式")
@ApiResponse(code = 200, message = "返回的是json格式", response = Resp.class)
public Resp getThirdSysRouterInDubbo(HttpServletRequest request) {
String traceId = MDC.get(ContextCommonMsg.TRACE_ID);
String username = request.getParameter("username");
if (StringUtils.isEmpty(username)) {
username = "郭童";
}
return dubboRPCThirdSysRouterService.getUserManagerService_Hello(traceId, username);
} @GlobalTransactional
@RequestMapping(value = "/dubbo_seata_thirdsysrouter", method = RequestMethod.GET)
@ApiOperation(value = "usermanager服务调用thirdsysrouter分布式事务", notes = "json格式")
@ApiResponse(code = 200, message = "返回的是json格式", response = Resp.class)
public Resp getThirdSysRouterInDubboBySeata(HttpServletRequest request) {
String traceId = MDC.get(ContextCommonMsg.TRACE_ID);
String username = request.getParameter("username");
if (StringUtils.isEmpty(username)) {
username = "郭童";
}
// 插入本地数据库
GpLogin gpLogin = new GpLogin().
setUsername("GlobalTransactional" + username)
.setPassword("dubbo_seata_thirdsysrouter")
.setWelcomeName("分布式事务" + traceId);
gpLoginService.save(gpLogin);
log.info("第一段插入数据库study库成功" + gpLogin.getId());
Resp resp = dubboRPCThirdSysRouterService.databaseUpdate(gpLogin);
log.info("分布式事务----结束,第二段插入数据库study02-id={},响应码=" + resp.getCode(), resp.getData());
int j = 100 / 0;
return resp;
}
}

Seata的核心注解: 全局AT的undolog依赖关系型数据库的事务 开启@GlobalTransactional

Dubbo的核心注解: 调用方:@DubboReference 被调方: @DubboService

省略。。。。。。。。

项目二 ThirdSysRouterApp :8099

配合+依赖和项目一类似,使用不同的数据库和一张表。。。。。。。。。

项目一的Dubbo调用项目二的方法

/**
* @description: 基于dubbo实现远程过程调用
* @author: GuoTong
* @createTime: 2022-09-24 17:40
* @since JDK 1.8 OR 11
**/
@Service
@DubboService
@Slf4j
public class DubboRouterService implements RemoteUserManageService { @Autowired
private GotoUserManagerService gotoUserManagerService; @Autowired
private StudentService studentService; /**
* Description: Dubbo的消息提供方 @DubboService
*
* @author: GuoTong
* @date: 2022-09-24 17:42:36
*/ @Override
public Resp<Map<String, Object>> getUserManagerService_Hello(String TraceId, String userName) {
log.info("[{}]dubbo 方式请求进入了!!!!", TraceId);
Resp<Map<String, Object>> mapData = gotoUserManagerService.createMapData();
Map<String, Object> data = mapData.getData();
data.put("TraceId", TraceId);
data.put("userName", userName);
return mapData;
} @Override
public Resp databaseUpdate(Object gpLogin) {
Student gpLogin2 = null;
if (gpLogin instanceof GpLogin) {
Long id = ((GpLogin) gpLogin).getId();
if (id != null && id > 0) {
// 插入本地数据库
gpLogin2 = new Student().
setUsername("thirdsysrouter")
.setPassword("thirdsysrouter")
.setPwdShow("分布式事务thirdsysrouter");
studentService.save(gpLogin2);
// 执照异常,利用分布式事务回滚 int i = 100 / 0;
}
}
return gpLogin2 != null ? Resp.Ok(gpLogin2.getId()) : Resp.error("利用分布式事务");
}
}

启动两个项目演示

输入项目一调用项目二的SwaggerUI接口测试地址

http://localhost:10085/doc.html#/default/测试接口/getThirdSysRouterInDubboBySeataUsingGET

执行调用

分析响应结果,由于手动制造了异常,被全局异常捕获,响应结果成功

查看A库A表和B库B表是否插入成功

A库A表没有插入成功:分布式事务关键字的一条记录



B库B表没有插入成功:分布式事务关键字的一条记录

数据库结果是成功的,同时回滚了。。。

查看日志

A服务请求进入。执行了A库A表插入成功

继续日志Dubbo 去RPC调用B服务了

2023-07-07 18:23:43.322 INFO 14568 --- [io-10085-exec-9] c.g.s.DubboRPCThirdSysRouterService : [7db0c75b-8a65-4d31-84cb-6cdd14d580a4] [Seata]:dubbo RPC方式请求发送出去!!!!

B服务执行方法;B库B表插入成功响应-->A系统

A系统收到B'系统的响应:



A系统收到B'系统的响应继续走:触发除零异常

A系统:触发全局异常处理



中间触发了这几个Seata二阶段提交的关键字日志

这时候意思很明显 失败回滚;去掉除零异常再测试

代码优化一下:由前端传入参数控制是否触发异常区回滚

测试:界面返回操作成功

测试:数据库是否操作成功

B系统:



A系统

验证通过。。。

再测试失败全局事物回滚::



结束。。。。。。。。。。。。

更详细参考Gitee完整的项目:https://gitee.com/gtnotgod/Springcloud-alibaba.git

Springcloud2021+Nacos2.2+Dubbo3+Seata1.6实现分布式事务的更多相关文章

  1. 对比7种分布式事务方案,还是偏爱阿里开源的Seata,真香!(原理+实战)

    前言 这是<Spring Cloud 进阶>专栏的第六篇文章,往期文章如下: 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强? openFeign夺命连环9问,这谁受得了? 阿里面 ...

  2. SpringCloud微服务实战——搭建企业级开发框架(二十七):集成多数据源+Seata分布式事务+读写分离+分库分表

    读写分离:为了确保数据库产品的稳定性,很多数据库拥有双机热备功能.也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器:第二台数据库服务器,主要进行读的操作. 目前有多种方式实现读写分离,一种 ...

  3. 群集中的MS DTC分布式事务协调器

    MS DTC在大多数SQL 服务器下都需要安装,若只是安装数据库引擎或Analysis 服务可不安装DTC.如果后需要使用分布式事务,则可在SQL Server群集安装完成后再安装DTC. 一.群集M ...

  4. 事务使用中如何避免误用分布式事务(System.Transactions.TransactionScope)

    1:本地事务DbTransaction和分布式事务TransactionScope的区别: 1.1:System.Data.Common.DbTransaction: 本地事务:这个没什么好说了,就是 ...

  5. 没有活动事务 链接服务器的 OLE DB 访问接口 "SQLNCLI" 无法启动分布式事务

    在windows2003下执行分布式事务的时候出现如下情况. 一. 问题现象在执行分布式事务时,在sql server 2005下收到如下错误: 链接服务器"xxxxxxx"的 O ...

  6. 已禁用对分布式事务管理器(MSDTC)的网络访问的解决方法之一

    C# ASP.NET项目提示上述错误,在代码中使用分布式事务提示添加或修改到数据库的时候.添加数据到数据库时,不会设置实体类的主键字段.

  7. 【转】PostgreSQL分布式事务配置

    XA是open group提出的分布式事务处理规范,JTA支持XA规范,JTA只规定了接口,有些应用容器提供实现,也有一些三方的开源实现可用,比如Atomikos. 如果PostgreSQL参与分布式 ...

  8. 分布式事务(一)两阶段提交及JTA

    原创文章,同步发自作者个人博客 http://www.jasongj.com/big_data/two_phase_commit/ 分布式事务 分布式事务简介 分布式事务是指会涉及到操作多个数据库(或 ...

  9. 关于分布式事务的一个误解:使用了TransactionScope就一定会开启分布式事务吗?

    背景: 事务是数据库管理系统的一个基本概念,事务具有四个基本特点,即ACID:原子性(Atomicity).一致性(Consistency).隔离性(Isolation)和持久性(Durability ...

  10. 分布式事务操作之Spring+JTA

    什么是分布式事务?在网上找了一段比较容易理解的"定义". 分布式事务是指事务的参与者.支持事务的服务器.资源管理器以及事务管理器分别位于分布系统的不同节点之上,在两个或多个网络计算 ...

随机推荐

  1. mysql的查询--子查询,order by,group by,having

    一. 1.多表查询 格式1: select 字段列表 from 表1 join 表2 on 表1.字段1=表2.字段1 where 查询条件 格式2: select 字段列表 from 表1 join ...

  2. 在 Rainbond 上使用在线知识库系统zyplayer-doc

    zyplayer-doc 是一款适合企业和个人使用的WIKI知识库管理工具,提供在线化的知识库管理功能,专为私有化部署而设计,最大程度上保证企业或个人的数据安全,可以完全以内网的方式来部署使用它. 当 ...

  3. Nuxtjs实现服务端渲染和静态化站点

    本文将介绍如何使用Nuxtjs对vue项目进行ssr和静态化处理. Nuxtjs简单介绍 首先,我们简单了解下Nuxtjs框架,Nuxt.js是一个基于Vue的通用框架,主要用于解决Vue项目的服务端 ...

  4. UniApp小程序开发如何获取用户手机号

    我们在小程序开发的时候经常遇到这种需求,需要在账号登陆的时候进行手机号获取,并使用手机号登陆. 本文讲述如何在前后端分离的状态下获取手机号 查阅官网文档不难发现我们需要使用uni.login()这个方 ...

  5. 揭开神秘面纱,会stream流就会大数据

    目录 准备工作 1.map类 1.1 java stream map 1.2 spark map 1.2.1 MapFunction 1.2.2 MapPartitionsFunction 2.fla ...

  6. Python OOP之继承封装多态

    面向对象的三大特征 继承 封装 多态 继承 子类可以使用父类定义的内容或者行为 继承的实现 父类,基类,超类,被继承的类,Base Class,Super Class 子类:有继承行为的类 所有类都必 ...

  7. [OpenCV-Python] 17 形态学转换

    文章目录 OpenCV-Python:IV OpenCV中的图像处理 17 形态学转换 17.1 腐蚀 17.2 膨胀 17.3 开运算 17.4 闭运算 17.5 形态学梯度 17.6 礼帽 17. ...

  8. sqlmap安全测试工具使用简介

    SQLmap是一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL的SQL注入漏洞,目前支持的数据库是MySQL,Oracle,PostgreSQL,Microsoft  SQL  S ...

  9. spring事务传播的Propagation.REQUIRES_NEW以及NEVER MANDATORY验证,及其失效的诡异问题

    NEVER 不使用事务,如果当前事务存在,则抛出异常 验证: @Service public class PrService { @Autowired PrDao dao; @Transactiona ...

  10. map和multimap

    map相对于set区别,map具有键值和实值,所有元素根据键值自动排序,pair的第一个值被称为键值key,pair的第二个值被称为实值value.map也是以红黑树为底层实现机制,根据key进行排序 ...