Comments (7)
实现是可以实现,但是觉得这种写法很挫。不用 @Transaction
修饰器是因为 typeorm
在 0.4.0
版本好像是要删掉这些修饰器的
from nestjs-learning.
而且通过查看typeorm日志发现好像这种写法的话,没执行到最后就已经 commit
了
query: START TRANSACTION
query: INSERT INTO `post`(`id`, `created_at`, `update_at`, `deleted_at`, `type`, `title`, `sub_title`, `description`, `uid`, `content`, `status`, `cover`) VALUES (DEFAULT, DEFAULT, DEFAULT, DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?) -- PARAMETERS: [0,"搭建 git 服务器","","",11,"1. 安装git:\n\n```cmd\n$ sudo apt-get install git\n```\n\n> [CentOS安装最新版git](https://my.oschina.net/antsky/blog/514586)\n\n2. 创建一个git用户,用来运行git服务:\n\n```cmd\n$ sudo adduser git\n```\n3. 创建证书登录:\n\n 收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。\n\n4. 初始化Git仓库:\n\n 先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:\n\n```cmd\n$ sudo git init --bare sample.git\n```\n Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git:\n\n```cmd\n$ sudo chown -R git:git sample.git\n```\n5. 禁用shell登录:\n\n 出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:\n\n```\ngit:x:1001:1001:,,,:/home/git:/bin/bash\n```\n\n 改为:\n```\ngit:x:1001:1001:,,,:/home/git:/usr/bin/git-shell\n```\n\n 这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。\n\n6. 克隆远程仓库:\n\n 现在,可以通过git clone命令克隆远程仓库了,在各自的电脑上运行:\n\n```cmd\n$ git clone git@server:/srv/sample.git\nCloning into 'sample'...\nwarning: You appear to have cloned an empty repository.\n```\n\n### 管理公钥\n如果团队很小,把每个人的公钥收集起来放到服务器的/home/git/.ssh/authorized_keys文件里就是可行的。\n\n### 来源\n- [廖雪峰的官方网站](http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137583770360579bc4b458f044ce7afed3df579123eca000)\n",1,"https://images.unsplash.com/photo-1547981607-6ea66fe762b4?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=900&h=600&fit=crop&ixid=eyJhcHBfaWQiOjF9"]
query: SELECT `PostEntity`.`id` AS `PostEntity_id`, `PostEntity`.`created_at` AS `PostEntity_created_at`, `PostEntity`.`update_at` AS `PostEntity_update_at`, `PostEntity`.`type` AS `PostEntity_type` FROM `post` `PostEntity` WHERE `PostEntity`.`id` = ? -- PARAMETERS: [18]
query: SELECT `CateEntity`.`id` AS `CateEntity_id`, `CateEntity`.`created_at` AS `CateEntity_created_at`, `CateEntity`.`update_at` AS `CateEntity_update_at`, `CateEntity`.`deleted_at` AS `CateEntity_deleted_at`, `CateEntity`.`name` AS `CateEntity_name`, `CateEntity`.`pid` AS `CateEntity_pid`, `CateEntity`.`cover` AS `CateEntity_cover`, `CateEntity`.`description` AS `CateEntity_description` FROM `cate` `CateEntity` WHERE `CateEntity`.`id` IN (?) LIMIT 1 -- PARAMETERS: [2]
query: SELECT `CateEntity`.`id` AS `CateEntity_id`, `CateEntity`.`created_at` AS `CateEntity_created_at`, `CateEntity`.`update_at` AS `CateEntity_update_at`, `CateEntity`.`deleted_at` AS `CateEntity_deleted_at`, `CateEntity`.`name` AS `CateEntity_name`, `CateEntity`.`pid` AS `CateEntity_pid`, `CateEntity`.`cover` AS `CateEntity_cover`, `CateEntity`.`description` AS `CateEntity_description` FROM `cate` `CateEntity` WHERE `CateEntity`.`id` IN (?) LIMIT 1 -- PARAMETERS: [3]
query: START TRANSACTION
query: START TRANSACTION
query: INSERT INTO `cate_relation`(`id`, `created_at`, `update_at`, `deleted_at`, `cid`, `compose_id`, `compose_type`) VALUES (DEFAULT, DEFAULT, DEFAULT, DEFAULT, ?, ?, ?) -- PARAMETERS: [2,18,1]
query: INSERT INTO `cate_relation`(`id`, `created_at`, `update_at`, `deleted_at`, `cid`, `compose_id`, `compose_type`) VALUES (DEFAULT, DEFAULT, DEFAULT, DEFAULT, ?, ?, ?) -- PARAMETERS: [3,18,1]
query: SELECT `CateRelationEntity`.`id` AS `CateRelationEntity_id`, `CateRelationEntity`.`created_at` AS `CateRelationEntity_created_at`, `CateRelationEntity`.`update_at` AS `CateRelationEntity_update_at` FROM `cate_relation` `CateRelationEntity` WHERE `CateRelationEntity`.`id` = ? -- PARAMETERS: [20]
query: SELECT `CateRelationEntity`.`id` AS `CateRelationEntity_id`, `CateRelationEntity`.`created_at` AS `CateRelationEntity_created_at`, `CateRelationEntity`.`update_at` AS `CateRelationEntity_update_at` FROM `cate_relation` `CateRelationEntity` WHERE `CateRelationEntity`.`id` = ? -- PARAMETERS: [21]
query: COMMIT
query: COMMIT
query: SELECT `TagEntity`.`id` AS `TagEntity_id`, `TagEntity`.`created_at` AS `TagEntity_created_at`, `TagEntity`.`update_at` AS `TagEntity_update_at`, `TagEntity`.`deleted_at` AS `TagEntity_deleted_at`, `TagEntity`.`name` AS `TagEntity_name`, `TagEntity`.`pid` AS `TagEntity_pid`, `TagEntity`.`color` AS `TagEntity_color`, `TagEntity`.`description` AS `TagEntity_description` FROM `tag` `TagEntity` WHERE `TagEntity`.`name` = ? LIMIT 1 -- PARAMETERS: ["git"]
query: START TRANSACTION
query: INSERT INTO `tag_relation`(`id`, `created_at`, `update_at`, `deleted_at`, `tag_id`, `compose_id`, `compose_type`) VALUES (DEFAULT, DEFAULT, DEFAULT, DEFAULT, ?, ?, ?) -- PARAMETERS: [7,18,1]
query: SELECT `TagRelationEntity`.`id` AS `TagRelationEntity_id`, `TagRelationEntity`.`created_at` AS `TagRelationEntity_created_at`, `TagRelationEntity`.`update_at` AS `TagRelationEntity_update_at` FROM `tag_relation` `TagRelationEntity` WHERE `TagRelationEntity`.`id` = ? -- PARAMETERS: [5]
query: COMMIT
query: COMMIT
是不是我哪个地方的理解有问题?
from nestjs-learning.
哦,我可能知道为什么提前commit了,是不是只能通过调用manager方法去进行事务的原因....
from nestjs-learning.
更改后就正常了
query: START TRANSACTION
query: INSERT INTO `post`(`id`, `created_at`, `update_at`, `deleted_at`, `type`, `title`, `sub_title`, `description`, `uid`, `content`, `status`, `cover`) VALUES (DEFAULT, DEFAULT, DEFAULT, DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?) -- PARAMETERS: [0,"搭建 git 服务器2","","",11,"1. 安装git:\n\n```cmd\n$ sudo apt-get install git\n```\n\n> [CentOS安装最新版git](https://my.oschina.net/antsky/blog/514586)\n\n2. 创建一个git用户,用来运行git服务:\n\n```cmd\n$ sudo adduser git\n```\n3. 创建证书登录:\n\n 收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。\n\n4. 初始化Git仓库:\n\n 先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:\n\n```cmd\n$ sudo git init --bare sample.git\n```\n Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git:\n\n```cmd\n$ sudo chown -R git:git sample.git\n```\n5. 禁用shell登录:\n\n 出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:\n\n```\ngit:x:1001:1001:,,,:/home/git:/bin/bash\n```\n\n 改为:\n```\ngit:x:1001:1001:,,,:/home/git:/usr/bin/git-shell\n```\n\n 这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。\n\n6. 克隆远程仓库:\n\n 现在,可以通过git clone命令克隆远程仓库了,在各自的电脑上运行:\n\n```cmd\n$ git clone git@server:/srv/sample.git\nCloning into 'sample'...\nwarning: You appear to have cloned an empty repository.\n```\n\n### 管理公钥\n如果团队很小,把每个人的公钥收集起来放到服务器的/home/git/.ssh/authorized_keys文件里就是可行的。\n\n### 来源\n- [廖雪峰的官方网站](http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137583770360579bc4b458f044ce7afed3df579123eca000)\n",1,"https://images.unsplash.com/photo-1547981607-6ea66fe762b4?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=900&h=600&fit=crop&ixid=eyJhcHBfaWQiOjF9"]
query: SELECT `PostEntity`.`id` AS `PostEntity_id`, `PostEntity`.`created_at` AS `PostEntity_created_at`, `PostEntity`.`update_at` AS `PostEntity_update_at`, `PostEntity`.`type` AS `PostEntity_type` FROM `post` `PostEntity` WHERE `PostEntity`.`id` = ? -- PARAMETERS: [19]
query: SELECT `CateEntity`.`id` AS `CateEntity_id`, `CateEntity`.`created_at` AS `CateEntity_created_at`, `CateEntity`.`update_at` AS `CateEntity_update_at`, `CateEntity`.`deleted_at` AS `CateEntity_deleted_at`, `CateEntity`.`name` AS `CateEntity_name`, `CateEntity`.`pid` AS `CateEntity_pid`, `CateEntity`.`cover` AS `CateEntity_cover`, `CateEntity`.`description` AS `CateEntity_description` FROM `cate` `CateEntity` WHERE `CateEntity`.`id` IN (?) LIMIT 1 -- PARAMETERS: [2]
query: SELECT `CateEntity`.`id` AS `CateEntity_id`, `CateEntity`.`created_at` AS `CateEntity_created_at`, `CateEntity`.`update_at` AS `CateEntity_update_at`, `CateEntity`.`deleted_at` AS `CateEntity_deleted_at`, `CateEntity`.`name` AS `CateEntity_name`, `CateEntity`.`pid` AS `CateEntity_pid`, `CateEntity`.`cover` AS `CateEntity_cover`, `CateEntity`.`description` AS `CateEntity_description` FROM `cate` `CateEntity` WHERE `CateEntity`.`id` IN (?) LIMIT 1 -- PARAMETERS: [3]
query: INSERT INTO `cate_relation`(`id`, `created_at`, `update_at`, `deleted_at`, `cid`, `compose_id`, `compose_type`) VALUES (DEFAULT, DEFAULT, DEFAULT, DEFAULT, ?, ?, ?) -- PARAMETERS: [2,19,1]
query: INSERT INTO `cate_relation`(`id`, `created_at`, `update_at`, `deleted_at`, `cid`, `compose_id`, `compose_type`) VALUES (DEFAULT, DEFAULT, DEFAULT, DEFAULT, ?, ?, ?) -- PARAMETERS: [3,19,1]
query: SELECT `CateRelationEntity`.`id` AS `CateRelationEntity_id`, `CateRelationEntity`.`created_at` AS `CateRelationEntity_created_at`, `CateRelationEntity`.`update_at` AS `CateRelationEntity_update_at` FROM `cate_relation` `CateRelationEntity` WHERE `CateRelationEntity`.`id` = ? -- PARAMETERS: [22]
query: SELECT `CateRelationEntity`.`id` AS `CateRelationEntity_id`, `CateRelationEntity`.`created_at` AS `CateRelationEntity_created_at`, `CateRelationEntity`.`update_at` AS `CateRelationEntity_update_at` FROM `cate_relation` `CateRelationEntity` WHERE `CateRelationEntity`.`id` = ? -- PARAMETERS: [23]
query: SELECT `TagEntity`.`id` AS `TagEntity_id`, `TagEntity`.`created_at` AS `TagEntity_created_at`, `TagEntity`.`update_at` AS `TagEntity_update_at`, `TagEntity`.`deleted_at` AS `TagEntity_deleted_at`, `TagEntity`.`name` AS `TagEntity_name`, `TagEntity`.`pid` AS `TagEntity_pid`, `TagEntity`.`color` AS `TagEntity_color`, `TagEntity`.`description` AS `TagEntity_description` FROM `tag` `TagEntity` WHERE `TagEntity`.`name` = ? LIMIT 1 -- PARAMETERS: ["git"]
query: INSERT INTO `tag_relation`(`id`, `created_at`, `update_at`, `deleted_at`, `tag_id`, `compose_id`, `compose_type`) VALUES (DEFAULT, DEFAULT, DEFAULT, DEFAULT, ?, ?, ?) -- PARAMETERS: [7,19,1]
query: SELECT `TagRelationEntity`.`id` AS `TagRelationEntity_id`, `TagRelationEntity`.`created_at` AS `TagRelationEntity_created_at`, `TagRelationEntity`.`update_at` AS `TagRelationEntity_update_at` FROM `tag_relation` `TagRelationEntity` WHERE `TagRelationEntity`.`id` = ? -- PARAMETERS: [6]
query: COMMIT
from nestjs-learning.
更改后的函数:
async create(createPostDto: CreatePostDto): Promise<PostEntity> {
return await getManager().transaction(async manager => {
const defaultCover = `https://images.unsplash.com/
photo-1546623235-23f145a669ef?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=900&h=600&fit=crop&ixid=eyJhcHBfaWQiOjF9`;
const postDto: PostDto = {
title: createPostDto.title,
uid: createPostDto.uid,
content: createPostDto.content,
type: createPostDto.type,
status: createPostDto.status,
cover: createPostDto.cover || defaultCover,
subTitle: createPostDto.subTitle || '',
description: createPostDto.description || '',
};
// 保存文章
const post = await manager.save<PostEntity>(
manager.create<PostEntity>(PostEntity, postDto),
);
const postId = post.id;
// ------ 文章分类表
const cids = createPostDto.cids || [];
if (cids.length === 0) {
// 默认未分类
await manager.save<CateRelationEntity>(
manager.create<CateRelationEntity>(
CateRelationEntity,
{
cid: 14, // 未分类,
composeId: postId,
composeType: SourceType.POST,
},
),
);
} else {
const cates = await Promise.all(
_map(cids, cid => {
return this.cateService.findOne(cid);
}),
);
// 过滤不存在的分类
const existCates = _filter(cates, item => !_isUndefined(item));
// 批量插入分类文章映射
// TODO 待优化
const cateRaltions = await Promise.all(
_map(existCates, cate => {
return manager.save<CateRelationEntity>(
manager.create<CateRelationEntity>(CateRelationEntity, {
cid: cate.id,
composeId: postId,
composeType: SourceType.POST,
}),
);
}),
);
}
// -------- 文章标签表
const tagsName = createPostDto.tags || [];
if (tagsName.length) {
// 检测tag是否存在
const tags = await Promise.all(
_map(tagsName, t => {
return this.tagService.findByName(t);
}),
);
// 需要新增的tag
const newTags = [];
const newTagIndex = [];
const existTags: TagEntity[] = [...tags];
_forEach(tags, (tag, index) => {
if (_isUndefined(tag)) { // 为空即是不存在
newTags.push(tagsName[index]);
newTagIndex.push(index);
}
});
// 新增加的tag
const createTags = await Promise.all(
_map(newTags, t => {
return manager.save<TagEntity>(
manager.create<TagEntity>(TagEntity, {
name: t,
}),
);
}),
);
// 组合获取文章的标签详情数组
_forEach(createTags, (value, index) => {
const existIndex = newTagIndex[index];
existTags[existIndex] = value;
});
// 批量插入标签文章映射
// TODO 待优化
await Promise.all(
_map(existTags, et => {
return manager.save<TagRelationEntity>(
manager.create<TagRelationEntity>(TagRelationEntity, {
tagId: et.id,
composeId: postId,
composeType: SourceType.POST,
}),
);
}),
);
}
return post;
});
}
from nestjs-learning.
getManager().transaction()
此方法会自动回滚
要自己控制事物可以用如下方式:
// 获取连接生成 query runner
const queryRunner = getConnection().createQueryRunner();
// 开启事务
await queryRunner.startTransaction();
try {
const user = await queryRunner.manager.findOne(User, { id: userId });
user.nickname = 'new_nickname';
const article = await queryRunner.manager.findOne(Article, { id: articleId });
article.title = 'new_title';
// 保存 user 数据
await queryRunner.manager.save(user);
// 保存 article 数据
await queryRunner.manager.save(article);
// 提交事物
await queryRunner.commitTransaction();
} catch (error) {
// 回滚
await queryRunner.rollbackTransaction();
} finally {
// 释放连接
await queryRunner.release();
}
from nestjs-learning.
OK
from nestjs-learning.
Related Issues (20)
- Dependency Dashboard
- postgres在windows下安装失败,无法使用
- async findAll(): Cat[] { return this.cats; }
- 嵌套的module应该怎么使用啊? HOT 3
- @nestjs/passport 抛出异常错误无法拦截的吗? HOT 4
- guard中怎么注入service? HOT 2
- 启动 unable connect database HOT 2
- 老板讲讲nest cloud? HOT 1
- 上传文件时的异常
- graphql-api demo能完善auth 验证部分? HOT 1
- 学的人还是太少,都没人提问 HOT 1
- TypeORM createQueryBuilder groupBy FORMAT YYYY-MM-DD HOT 2
- 数据库更换为Sqlite3的简单方法
- 楼主有没有考虑出一个供多个端使用的 nestjs + mysql 的服务demo? HOT 1
- 遇到了单元测试的问题
- 使用nestjs/config,class在启动时获取不到process.env,如何解决 HOT 1
- typeorm连接数据库时,ormconfig.json entities的路径配置问题
- 继续更新吗?
- nestJS 中graphql 对bigint怎么处理
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nestjs-learning.