日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL调用mongodb事务回滚_SpringBoot整合MongoDB,在多数据源下实现事务回滚。

發布時間:2023/12/4 数据库 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL调用mongodb事务回滚_SpringBoot整合MongoDB,在多数据源下实现事务回滚。 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

項目中用到了MongoDB,準備用來存儲業務數據,前提是要實現事務,保證數據一致性,MongoDB從4.0開始支持事務,提供了面向復制集的多文檔事務特性。能滿足在多個操作,文檔,集合,數據庫之間的事務性,事務的特性。多文檔事務在4.0版本僅支持復制集,對分片集群的事務性支持計劃在4.2版本中實現。由于我也算是一個java小白,沒怎么弄清java事務機制,于是先建了個測試項目進行測試。在本例中可以看到多數據源下事務的使用,請重點關注后面記錄的爬坑記。

Mongo Transaction

項目介紹

springboot 2.1.3

MongoDB 4.0.3

本項目主要為了測試MongoDB事務,由于正式項目還用了其它數據源,所以加入了 Oracle, MySQL的事務,包括多數據源的配置和使用

使用說明

1.導入MongoDB的依賴

org.springframework.boot

spring-boot-starter-data-mongodb

2.配置MongoDB的連接

spring:

# mongodb 連接

data:

mongodb:

uri: mongodb://192.168.0.68:27017,192.168.0.69:27017,192.168.0.70:27017/glcloud?replicaSet=rs0

database: glcloud

3.編寫entity類

當id設置為 ObjectId 類型和添加 @Id 注解時時,MongoDB數據庫會自動生成主鍵,我們在保存對象時就不用設置id的值

MongoUnit

/**

* 用戶

* @author muyuer 182443947@qq.com

* @version 1.0

* @date 2019-02-25 09:10

*/

@Data

@Document(collection = "test_unit")

public class MongoUnit {

private static final long serialVersionUID = 1L;

/**

* Id

*/

@Id

private ObjectId id;

/**

* unitId

*/

private String unitId;

/**

* unitName

*/

private String unitName;

}

MongoUser

package com.example.demo.entity.mongo;

import lombok.Data;

import org.bson.types.ObjectId;

import org.springframework.data.annotation.Id;

import org.springframework.data.mongodb.core.mapping.Document;

/**

* 用戶

* @author muyuer 182443947@qq.com

* @version 1.0

* @date 2019-02-25 09:10

*/

@Data

@Document(collection = "test_user")

public class MongoUser {

private static final long serialVersionUID = 1L;

/**

* Id

*/

@Id

private ObjectId id;

/**

* userId

*/

private String userId;

/**

* userName

*/

private String userName;

/**

* unitId 關聯testUser

*/

private String unitId;

}

4.編寫dao層的方法

只需繼承MongoRepository即可。

package com.example.demo.repository.mongo;

import com.example.demo.entity.mongo.MongoUser;

import org.springframework.data.mongodb.repository.MongoRepository;

/**

* @author muyuer 182443947@qq.com

* @version 1.0

* @date 2019-02-25 09:10

*/

public interface MongoUserRepository extends MongoRepository {

}

package com.example.demo.repository.mongo;

import com.example.demo.entity.mongo.MongoUnit;

import org.springframework.data.mongodb.repository.MongoRepository;

/**

* @author muyuer 182443947@qq.com

* @version 1.0

* @date 2019-02-25 09:10

*/

public interface MongoUnitRepository extends MongoRepository {

}

5.Service層

package com.example.demo.service.mongo.impl;

import com.example.demo.common.SystemException;

import com.example.demo.entity.mongo.MongoUser;

import com.example.demo.repository.mongo.MongoUserRepository;

import com.example.demo.service.mongo.MongoUserService;

import com.example.demo.common.R;

import com.example.demo.common.RUtil;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Propagation;

import org.springframework.transaction.annotation.Transactional;

/**

* @author muyuer 182443947@qq.com

* @version 1.0

* @date 2019-02-25 09:10

*/

@Service

@Slf4j

public class MongoUserServiceImpl implements MongoUserService {

@Autowired

MongoUserRepository mongoUserRepository;

/**

* 新增

* @param mongoUser

* @return

*/

@Override

public R save(MongoUser mongoUser) {

MongoUser mongoUserSave = mongoUserRepository.save(mongoUser);

log.info("用戶信息保存:testUserSave = "+ mongoUserSave);

return RUtil.success("");

}

@Override

@Transactional(value = "MONGO_TRANSACTION_MANAGER", propagation = Propagation.REQUIRED)

public R bathSave(String unitId, Boolean rollBack) {

for (int i = 0; i <= 10; i++) {

//注釋這段則可以正常添加數據,測試回滾則throw異常信息

if (unitId.equals("003") && rollBack) {

throw new SystemException("測試回滾故意拋出的異常");

}

MongoUser user = new MongoUser();

user.setUserId(unitId + "U0" + i);

user.setUserName("用戶" + i);

user.setUnitId(unitId);

save(user);

}

return RUtil.success("");

}

}

package com.example.demo.service.mongo.impl;

import com.example.demo.enums.REnum;

import com.example.demo.common.SystemException;

import com.example.demo.entity.mongo.MongoUnit;

import com.example.demo.repository.mongo.MongoUnitRepository;

import com.example.demo.service.mongo.MongoUnitService;

import com.example.demo.service.mongo.MongoUserService;

import com.example.demo.common.R;

import com.example.demo.common.RUtil;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**

* @author muyuer 182443947@qq.com

* @version 1.0

* @date 2019-02-25 09:10

*/

@Service

@Slf4j

public class MongoUnitServiceImpl implements MongoUnitService {

@Autowired

MongoUnitRepository mongoUnitRepository;

@Autowired

MongoUserService mongoUserService;

/**

* 新增

*

* @param unit

* @return

*/

@Override

public R save(MongoUnit unit) {

MongoUnit mongoUnitSave = mongoUnitRepository.save(unit);

log.info("單位信息保存:testUnitSave = " + mongoUnitSave);

return RUtil.success("");

}

@Override

@Transactional(value = "MONGO_TRANSACTION_MANAGER")

public R bathSave(Boolean rollBack) {

try {

for (int i = 0; i < 4; i++) {

MongoUnit unit = new MongoUnit();

unit.setUnitId("00" + i);

unit.setUnitName("單位" + i);

mongoUserService.bathSave(unit.getUnitId(),rollBack);

save(unit);

}

return RUtil.success("");

} catch (SystemException e) {

log.error("保存數據失敗:msg: {}", e.getMessage());

throw new SystemException(REnum.ERROR.getCode(), "保存數據失敗 Error:" + e.getMessage());

}

}

}

6.Controller

package com.example.demo.controller;

import com.example.demo.enums.DbTypeEnum;

import com.example.demo.service.mongo.MongoUserService;

import com.example.demo.common.R;

import com.example.demo.service.primary.PrimaryUserService;

import com.example.demo.service.slave.SlaveUserService;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

/**

* @author muyuer 182443947@qq.com

* @date 2019-02-25 10:59

*/

@RestController

@Slf4j

@RequestMapping(path="test/user")

public class TestUserController {

@Autowired

MongoUserService mongoUserService;

@Autowired

PrimaryUserService primaryUserService;

@Autowired

SlaveUserService slaveUserService;

/**

* 新增

* @param dbType

* @param unitId

* @param rollBack

* @return

*/

@PostMapping("/bathSave/{dbType}/{unitId}/{rollBack}")

public R bathSave(@PathVariable DbTypeEnum dbType, @PathVariable String unitId, @PathVariable Boolean rollBack){

switch (dbType) {

case MONGO:

return mongoUserService.bathSave(unitId, rollBack);

case PRIMARY:

return primaryUserService.bathSave(unitId, rollBack);

default:

return slaveUserService.bathSave(unitId, rollBack);

}

}

}

package com.example.demo.controller;

import com.example.demo.enums.DbTypeEnum;

import com.example.demo.service.mongo.MongoUnitService;

import com.example.demo.common.R;

import com.example.demo.service.primary.PrimaryUnitService;

import com.example.demo.service.slave.SlaveUnitService;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

/**

* @author muyuer 182443947@qq.com

* @date 2019-02-25 10:59

*/

@RestController

@Slf4j

@RequestMapping(path="test/unit")

public class TestUnitController {

@Autowired

MongoUnitService mongoUnitService;

@Autowired

PrimaryUnitService primaryUnitService;

@Autowired

SlaveUnitService slaveUnitService;

/**

* 新增

* @param dbType 數據庫

* @param rollBack 是否回滾

* @return

*/

@PostMapping("/bathSave/{dbType}/{rollBack}")

public R bathSave(@PathVariable DbTypeEnum dbType, @PathVariable Boolean rollBack) {

switch (dbType) {

case MONGO:

return mongoUnitService.bathSave(rollBack);

case PRIMARY:

return primaryUnitService.bathSave(rollBack);

default:

return slaveUnitService.bathSave(rollBack);

}

}

}

測試

PostMan post 地址

在實際應用中爬過的坑

1.MongoDB的版本必須是4.0

2.MongoDB事務功能必須是在多副本集的情況下才能使用,否則報錯"Sessions are not supported by the MongoDB cluster to which this client is connected",4.2版本會支持分片事務。

3.事務控制只能用在已存在的集合中,也就是集合需要手工添加不會由jpa創建會報錯"Cannot create namespace glcloud.test_user in multi-document transaction."

4.多數據源時需要指定事務 @Transactional(value = "transactionManager") 如果只有1個數據源不需要指定value

5.事務注解到類上時,該類的所有 public 方法將都具有該類型的事務屬性,但一般都是注解到方法上便于實現更精確的事務控制

6.事務傳遞性,事務子方法上不必添加事務注解,如果子方法也提供api調用可用注解propagation = Propagation.REQUIRED也就是繼承調用它的事務,如果沒有事務則新起一個事務

7.啟動類上的@EnableTransactionManagement注解,并不是像網上所說必需添加的注解,因為spring boot 默認開始了這個注解的。

8.有人說:注解必須是@Transactional(rollbackFor = { Exception.class }) 測試并不需要rollbackFor = { Exception.class },因為本例中自定義異常類繼承自RuntimeException spring boot事物默認在遇到RuntimeException不論rollbackFor的異常是啥,都會進行事務的回滾,加上rollbackFor=Exception.class,可以讓事物在遇到非運行時異常時也回滾

具體rollbackFor用法可參考:

參考文檔

總結

以上是生活随笔為你收集整理的MySQL调用mongodb事务回滚_SpringBoot整合MongoDB,在多数据源下实现事务回滚。的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲AV无码成人精品区先锋 | 免费的理伦片在线播放 | 第一色影院 | 国产成人精品无码播放 | 国产一区黄 | 国产精品白嫩白嫩大学美女 | 九色av| 少妇真人直播免费视频 | www日本com | 日本狠狠操 | 久久久88 | 亚洲最大在线视频 | 先锋影音av资源在线观看 | 偷拍亚洲色图 | 中文资源在线观看 | 韩国不卡av | 蜜臀av中文字幕 | 精品国产av一区二区 | 综合久久网 | 男女午夜爽爽爽 | 国产三级做爰高清在线 | 影音先锋在线观看视频 | 久草国产在线视频 | 成人77777 | 天天干影院 | gogo亚洲国模私拍人体 | 男女做的视频 | 丝袜国产视频 | 午夜簧片 | 捆绑中国女人hd视频 | 天天射日日 | 国产区在线看 | 久久网站免费看 | 亚洲欧洲日韩在线 | 亚洲色成人网站www永久四虎 | 91精品视频免费看 | 国产 丝袜 欧美中文 另类 | 久草精品在线观看 | 国产在线观看中文字幕 | 香蕉污视频 | 国产网站免费看 | 在线不卡视频 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 人妻视频一区二区三区 | 国产一区二区三区四 | 日本91网站| 欧洲亚洲女同hd | 日本护士体内she精2xxx | av制服丝袜在线 | 色秀视频网 | 国产综合在线观看视频 | 精品国产69 | 国产成人短视频 | 新婚若妻侵犯中文字幕 | 男人久久 | 国产aaaaa毛片| www四虎影院| 开心激情av | 成年人精品 | 国产三级av片| 在线观看亚洲网站 | 在线看片网址 | 久久久久久国产精品免费播放 | 一区二区在线观看视频 | 亚洲色图88| 久久久久国产一区二区三区 | 毛片一级片 | 女人被狂躁c到高潮喷水电影 | 久久激情免费视频 | 中文字幕乱码在线 | 中国字幕一色哟哟 | www.五月激情 | 日本黄色大片网站 | 一区二区成人精品 | 在线只有精品 | 青青草成人影视 | av激情久久 | 另类视频在线观看 | hs在线观看| 国产精品自拍片 | 在线免费观看你懂的 | 亚洲成年人在线观看 | 波多野结衣视频网址 | 麻豆国产精品视频 | 欧美无砖专区免费 | 午夜激情导航 | 亚洲综合视频在线 | 黑人三级视频 | 国产日韩欧美一区 | 超碰免费看 | 铠甲勇士猎铠 | 天堂在线一区 | 亚洲视频网站在线 | 久久麻豆av| 少妇姐姐 | 天堂激情网| 亚洲一区二区三区无码久久 | 欧美日本高清 | 黄色片大全|