在PostgreSQL中,公用表表达式(CTE)是优化范围.这意味着CTE已实现为内存,并且来自另一个查询的谓词永远不会被推入CTE.
现在我想知道关于CTE的其他元数据(例如排序)是否与其他查询共享.我们来看看以下问题:
WITH ordered_objects AS
(
SELECT * FROM object ORDER BY type ASC LIMIT 10
)
SELECT MIN(type) FROM ordered_objects
Run Code Online (Sandbox Code Playgroud)
在这里,MIN(type)显然总是第一行ordered_objects(或者NULL如果ordered_objects是空的),因为ordered_objects已经被排序了type.这些知识ordered_objects在评估时是否可用SELECT MIN(type) FROM ordered_objects?
假设some_table有两行,主键1和2.以下语句序列可能导致死锁:
session 1: begin;
session 2: begin;
session 1: DELETE FROM my_table WHERE my_key = 1;
session 2: DELETE FROM my_table WHERE my_key = 2;
session 1: DELETE FROM my_table WHERE my_key = 2;
session 2: DELETE FROM my_table WHERE my_key = 1;
Run Code Online (Sandbox Code Playgroud)
如果两个会话以相同的顺序删除,则不会发生死锁.
现在,回答我的问题,如果DELETE语句触及多行会发生什么?例如:
session 1: begin;
session 2: begin;
session 1: DELETE FROM my_table;
session 2: DELETE FROM my_table;
Run Code Online (Sandbox Code Playgroud)
是否有可能两个并发但相同的DELETE语句将以不同的顺序删除行?是否可以强制执行删除顺序以避免死锁?
我在文档中找不到这些信息,所以我想说不能保证删除顺序(尽管它可能间接地作为实现细节).我想在这里仔细检查一下.
我有以下情况:
我启动Camel路线如下:
public class MyMessage implements Runnable {
public void run() {
// omitted here
}
}
from("netty:tcp://localhost:7777?textline=true&sync=false")
... // omitted here: parse message to pojo MyMessage, set header "group-identifier"
.to(seda:process);
Run Code Online (Sandbox Code Playgroud)
此Camel路由使用TCP流,解析每个传入消息的有效负载并将其转换为MyMessagepojo,并group-identifier在交换机上设置与消息对应的标头...
现在我想消费seda:process如下:
run().我想为此提供/定义一个ExecutorService,所以我可以控制线程数.我可以在这里应用哪些企业集成模式?我如何将这些概念映射到Camel?
我了解到ActiveMQ具有消息组的概念(http://activemq.apache.org/message-groups.html).这可能提供一种方法来确保同一组中的两条消息永远不会同时执行.虽然,我不确定仅为此引入ActiveMQ并不是一种矫枉过正.这可以通过'核心'Camel/Java来实现吗?
java architecture concurrency apache-camel enterprise-integration
我想在Docker容器中使用GIT.https://hub.docker.com/r/alpine/git/上记录的用法 非常简单:
docker run -it --rm -v ${HOME}:/root -v $(pwd):/git alpine/git clone ...
Run Code Online (Sandbox Code Playgroud)
这有效.这有一个很大的缺点是所有文件现在都归root,而不是当前用户.我想解决这个问题,但到目前为止我都失败了.
我目前的命令是:
docker run -it --rm
--user $(id -u):$(id -g)
-v $HOME:$HOME:rw
-v /etc/passwd:/etc/paswd:ro
-v /etc/group:/etc/group:ro
-v $PWD:$PWD:rw
-w $PWD
alpine/git
clone ...
Run Code Online (Sandbox Code Playgroud)
在这里,我传递--user $(id -u):$(id -g)给当前用户.此外,我正在传递$HOME,/etc/passwd并/etc/group允许容器解析当前用户和主目录.
这会出现以下错误:No user exists for uid 1000.它来自何处以及如何解决?
版本信息:docker run -it --rm alpine/git --version给出git version 2.15.0
我maven-assembly-plugin用来组装不同的工件如下:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>configuration-staging</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
<execution>
<id>configuration-production</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
在assembly.xml,我启用了模板过滤:
<fileSets>
<fileSet>
<filtered>true</filtered>
Run Code Online (Sandbox Code Playgroud)
这非常有效.例如,如果我输入${name}要组装的其中一个资源,则将其替换为项目名称.我还可以定义属性pom.xml,它将被插件替换.
现在,我希望每次执行都有不同的属性maven-assembly-plugin.例如,我想介绍一个${url}包含要在目标环境中使用的URL(staging以及production上面的示例).
这可能吗?怎么样?
这个问题可以被视为对我的评论的后续跟进可以两个并发但相同的DELETE语句导致死锁吗?.
我想知道my_status在以下语句中行是否按升序锁定:
SELECT 1 FROM my_table ORDER BY my_status FOR UPDATE;
Run Code Online (Sandbox Code Playgroud)
https://www.postgresql.org/docs/9.5/static/sql-select.html上有一句有趣的评论说:
SELECT在READ COMMITTED事务隔离级别运行的命令以及使用ORDER BY和锁定子句可能无序地返回行.这是因为ORDER BY首先应用.该命令对结果进行排序,但可能会阻止尝试获取一个或多个行的锁定.一旦SELECT疏导,一些排序列值可能已被修改,导致出现被淘汰的顺序(尽管它们是为了在原有的列值而言)的行.例如,可以通过将FOR UPDATE/SHARE子句放在子查询中来根据需要解决这个问题Run Code Online (Sandbox Code Playgroud)SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1;
我不确定这是否能回答我的问题.所有这些都是ORDER BY首先应用的,并且您需要放入FOR UPDATE子查询来解决副作用,如果在此期间更改了订单列的值,实际输出顺序可能会有所不同.换句话说,放入FOR UPDATE子查询可确保在订购之前发生锁定.
但这并没有真正告诉我们这些行是否实际上是按照ORDER BY条款确定的顺序锁定的?
我正在针对PostgreSQL v12数据库进行开发。我正在使用SERIALIZABLE交易。一般想法是,当PostgreSQL检测到序列化异常时,应重试完整的事务。
我正在使用Spring的AbstractFallbackSQLExceptionTranslator将数据库异常转换为Spring的异常类。此异常翻译器应将PostgreSQL错误40001/serialization_failure转换为ConcurrencyFailureException。Spring JDBC维护一个映射文件,以将PostgreSQL特定的代码映射到数据库异常40001的通用cannotSerializeTransactionCodes类,该类将转换ConcurrencyFailureException为API用户。
我的想法是依靠Spring Retry项目重试SERIALIZABLE由于序列化错误而暂停的事务,如下所示:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Retryable(include = ConcurrencyFailureException.class, maxAttempts = ..., backoff = ...)
@Transactional(isolation = Isolation.SERIALIZABLE)
public @interface SerializableTransactionRetry {
}
Run Code Online (Sandbox Code Playgroud)
在服务实现,我会简单地替换@Transactional通过@SerializableTransactionRetry,并用它做。
现在,回到PostgreSQL。本质上,可以在两个阶段检测序列化异常:
似乎Spring AbstractFallbackSQLExceptionTranslator正确地转换了在执行语句期间检测到的序列化异常,但在提交阶段未能转换序列化异常。考虑以下堆栈跟踪:
org.springframework.transaction.TransactionSystemException: Could not commit JDBC transaction; nested exception is org.postgresql.util.PSQLException: ERROR: could not serialize access due to read/write dependencies among …Run Code Online (Sandbox Code Playgroud) postgresql ×4
sql ×3
apache-camel ×1
architecture ×1
concurrency ×1
docker ×1
etcpasswd ×1
git ×1
java ×1
maven ×1
maven-3 ×1
passwd ×1
spring ×1
spring-jdbc ×1
spring-retry ×1
transactions ×1
user-roles ×1