事务块是否会导致postgresql on db中的错误提交或应用程序崩溃?

事务块是否会导致postgresql on db中的错误提交或应用程序崩溃?,sql,postgresql,spring-boot,spring-mvc,transactions,Sql,Postgresql,Spring Boot,Spring Mvc,Transactions,我正在编写一个新模块,在这个模块中,我每天每分钟都会轮询卡夫卡的数千条记录,然后将它们分成两个表,然后提交给卡夫卡代理。我打算对前一天收集的几百万条记录进行一些汇总查询 我将记录分成两个表,因为负载本质上是动态的,我只对json负载中的几个字段感兴趣。我的假设是,即使在运行查询时,即使聚合只需在两列上运行,整行也会加载到数据库的内存中。因此,只需从一开始就将负责计数的列提取到一个单独的表中 客户计数其中,我对每种客户类型和每种采购类型的计数进行汇总查询 客户负载其中我计划稍后将完整负载归档到对象

我正在编写一个新模块,在这个模块中,我每天每分钟都会轮询卡夫卡的数千条记录,然后将它们分成两个表,然后提交给卡夫卡代理。我打算对前一天收集的几百万条记录进行一些汇总查询

我将记录分成两个表,因为负载本质上是动态的,我只对json负载中的几个字段感兴趣。我的假设是,即使在运行查询时,即使聚合只需在两列上运行,整行也会加载到数据库的内存中。因此,只需从一开始就将负责计数的列提取到一个单独的表中

客户计数其中,我对每种客户类型和每种采购类型的计数进行汇总查询

客户负载其中我计划稍后将完整负载归档到对象存储

我计划在一个事务块内进行批插入,首先插入到有效负载表,然后插入到计数表,假设由于异常、app或db崩溃导致在其中任何一个表中插入任何记录失败,会导致对这两个表的批插入回滚

由于我正在将每个事务的数千条记录写入两个表中,在提交过程中是否存在数据库崩溃或应用程序崩溃导致部分写入其中一个表的可能性

我的假设是,由于这是一个同步事务,在提交之前的任何数据库崩溃都会在db级别上回滚

对于spring启动应用程序中任何事务将不会提交的崩溃,也是如此

我非常谨慎,因为这些指标会导致下游的一些收入运营,因此存在部分承诺的可能性问题

这些桌子看起来有点像这样

计数表

create table customer_counts
(
id bigserial PK,
customer_id string Not Null,
count int,
purchase_type String,
process_dt date
) 
create index metric_counts_idx on (customer_id, purchase_type, process_dt)
有效载荷表

create table customer_payload
(
id bigserial PK,
customer_id string Not Null,
payload text,
process_dt date
) 
create index metric_payload_idx on (customer_id, process_dt)
然后我运行一个

select sum(count), customer_id, purchase_type 
from customer_counts 
group by customer_id, purchase_type
在一天结束时的计数表上记录了几百万条记录

我只是使用有效负载表来选择并推送到一个对象存储

PS:我还想知道在customer\u id、purchase\u type、count上创建一个索引是否可以避免为counts创建一个额外表的麻烦,但是从我读到的内容来看,索引只用于查找,聚合将在加载整行后运行。您无法保证查询计划器是否每次都考虑索引。关于这种方法的任何建议都将有助于将我的设计从两个表简化为一个表,将部分提交的问题限制在一个表中


我计划对事务和提交使用postgresql中的默认设置。我们使用SpringBootJDBCTemplate访问数据库,并在java应用程序级别使用
@Transactional
块。有效负载的大小在0.5 KB到10 KB之间变化。我还索引了客户id、购买类型和日期。postgres版本是9.6。

您将不会看到部分提交的事务。关于你的设置似乎没有什么令人担忧的

“整排”的事情并不完全正确。PG实际上一次加载一个内容,这通常意味着>1行-但一个页面将只包含相当紧凑的行数据,较大的值会被压缩并存储在带外(aka)。如果您既不选择也不筛选有效负载,则不应最终读取其大部分字段数据


至于你的私人秘书,我认为这实际上应该服从一个法律。在AIUI中,您将只进行插入,而不进行更新/删除,这意味着表的绝大多数对所有事务都是可见的,这是使仅索引扫描值得的一个重要因素。您可能希望对客户id、购买类型和计数使用一个索引,该索引可用于满足您的最终查询。

您将不会看到部分提交的交易。关于你的设置似乎没有什么令人担忧的

“整排”的事情并不完全正确。PG实际上一次加载一个内容,这通常意味着>1行-但一个页面将只包含相当紧凑的行数据,较大的值会被压缩并存储在带外(aka)。如果您既不选择也不筛选有效负载,则不应最终读取其大部分字段数据


至于你的私人秘书,我认为这实际上应该服从一个法律。在AIUI中,您将只进行插入,而不进行更新/删除,这意味着表的绝大多数对所有事务都是可见的,这是使仅索引扫描值得的一个重要因素。您可能希望在客户id、购买类型和计数上使用一个索引,这可以用来满足您的最终查询。

“每笔交易几千行”不是很大。“每笔交易几千行”不是很大。在PS中,我暗示,如果我只有一个带有客户id、购买类型的表,count and payload(计数和有效负载)使用客户id、购买类型、计数或客户id、购买类型和客户id与计数的索引,可以在索引上运行如select sum(计数)、purchase type(按购买类型从组合的购买计数有效负载表组中选择总和、购买类型)之类的查询,而不必执行整行扫描。如前所述,由于有效负载可能太大,我希望避免加载整行,只需获得计数的总和。我们是否也可以在事务块中使用循环插入来替换批量更新?在PS中,我暗示如果我只有一个表,其中包含customer\u id、purchase\u type、count和有效负载,其中包含customer\u id的索引,purchase_type、count或customer_id上的索引、purchase_type和customer_id和count上的另一个索引,可以从组合_counts_payload_表group by purchase_type中选择sum(count)、purchase_type这样的查询在索引上运行,而不必执行整行扫描。如前所述,由于有效负载可能太大,我希望避免加载整行,只需获得计数的总和。我们是否也可以在transac中使用循环插入