编辑:找到解决方案,向下看。
我们有一个Web应用程序,可以调用存储在 Sql Server 2012 数据库中的视图上的选择。
此查询失败并显示错误
"New request is not allowed to start because it should come with valid transaction descriptor"
此问题仅在单个客户数据库上发生,在所有其他客户模式上执行的相同查询运行正常。
在受影响的模式上自己在SSMS中执行的查询运行正常,仅在该特定模式的应用程序中失败。
SELECT语句是这样的:
select distinct clienti.numeroCliente,clienti.ragioneSociale,clienti.partitaIva,clienti.codiceFiscale,
clienti.SedeLegale,
clienti.mail,clienti.codiceContabilita,clienti.riferimentiCliente
from dbo.view_table clienti
where clienti.azienda = 'Company_name'
如果我们在其他Sql Server实例上本地恢复架构,我们可以复制错误。
我在互联网上搜索了很多,我找到的只是Sql Server 2005(https://support.microsoft.com/en-us/help/939285/fix-error-message-when-you-run-a-stored-procedure-that-starts-a-transaction-that-contains-a-transact-sql-statement-in-sql-server-2005-new-request-is-not-allowed-to-start-because-it-should-come-with-valid-transaction-descriptor)的修补程序,还有一些与分布式查询和索引碎片相关的帖子。
鉴于我可以复制问题,我可以尝试解决它吗?
运行查询的spring后端是Java,本机sql查询通过Hibernate运行。
Java 8
Spring 4.1.1
Hibernate 4.3.5
这是代码:
@Transactional(readOnly=true, isolation=Isolation.READ_UNCOMMITTED)
public List<ControlloContratto> caricaControlloContratti(FilterControlloContratti filter) {
List<ControlloContratto> lstCtrlContratti = null;
String dwhExtractionCCPQuery = "";
Session session = sessionManager.getFilteredSession(FilterType.NONE);
dwhExtractionCCPQuery = caricaControlloContrattiQuery(filter);
Query queryCallSP = session.createSQLQuery(dwhExtractionCCPQuery);
queryCallSP.setResultTransformer(Transformers.aliasToBean(ControlloContratto.class));
lstCtrlContratti = queryCallSP.setReadOnly(true).list();
}
我试图删除自定义隔离级别和只读注释,结果是一样的。
编辑:添加用于创建被调用视图的脚本
CREATE VIEW [dbo].[e3_dwh_view_clienti] AS
SELECT COALESCE(azienda.nome,'') azienda,
cliente.id idCliente,
cliente.numero numeroCliente,
cliente.ragione_sociale ragioneSociale,
COALESCE(cliente.partita_iva,'') partitaIva,
COALESCE(cliente.codice_fiscale,'') codiceFiscale,
natura.descrizione naturaCliente,
COALESCE((CASE WHEN tipoVia.descrizione IS NOT NULL AND pntStrad.fk_e0_decod_viario IS NULL
THEN tipoVia.descrizione
WHEN tipoVia.descrizione IS NULL AND pntStrad.fk_e0_decod_viario IS NULL
THEN ''
ELSE tipoVia2.descrizione
END),'') toponimo,
COALESCE((CASE WHEN tipoVia.descrizione IS NOT NULL AND pntStrad.fk_e0_decod_viario IS NULL
THEN pntStrad.indirizzo + ' ' + (CASE WHEN pntStrad.numero_civico IS NULL THEN '' ELSE pntStrad.numero_civico END)
+ (CASE WHEN pntStrad.esponente_civico IS NULL THEN '' ELSE '/'+pntStrad.esponente_civico END)
WHEN tipoVia.descrizione IS NULL AND pntStrad.fk_e0_decod_viario IS NULL
THEN pntStrad.indirizzo + ' ' + (CASE WHEN pntStrad.numero_civico IS NULL THEN '' ELSE pntStrad.numero_civico END)
+ (CASE WHEN pntStrad.esponente_civico IS NULL THEN '' ELSE '/'+pntStrad.esponente_civico END)
ELSE viario.denominazione + ' ' + (CASE WHEN pntStrad.numero_civico IS NULL THEN '' ELSE pntStrad.numero_civico END)
+ (CASE WHEN pntStrad.esponente_civico IS NULL THEN '' ELSE '/'+pntStrad.esponente_civico END)
END),'') indirizzo,
COALESCE(cap.codice,COALESCE(comune.cap,'')) cap,
COALESCE(comune.comune,'') comune,
COALESCE(comune.provincia,'') provincia,
COALESCE((CASE WHEN tipoVia.descrizione IS NOT NULL AND pntStrad.fk_e0_decod_viario IS NULL
THEN tipoVia.descrizione + ' ' + pntStrad.indirizzo + ' ' + (CASE WHEN pntStrad.numero_civico IS NULL THEN '' ELSE pntStrad.numero_civico END)
+ (CASE WHEN pntStrad.esponente_civico IS NULL THEN '' ELSE '/'+pntStrad.esponente_civico END) + ', ' +
(CASE WHEN cap.codice IS NULL THEN '' ELSE cap.codice END)+ ' '+ (CASE WHEN comune.comune IS NULL THEN '' ELSE comune.comune END)
WHEN tipoVia.descrizione IS NULL AND pntStrad.fk_e0_decod_viario IS NULL
THEN pntStrad.indirizzo + ' ' + (CASE WHEN pntStrad.numero_civico IS NULL THEN '' ELSE pntStrad.numero_civico END)
+ (CASE WHEN pntStrad.esponente_civico IS NULL THEN '' ELSE '/'+pntStrad.esponente_civico END) + ', ' +
(CASE WHEN cap.codice IS NULL THEN '' ELSE cap.codice END)+ ' '+ (CASE WHEN comune.comune IS NULL THEN '' ELSE comune.comune END)
ELSE tipoVia2.descrizione + ' ' + viario.denominazione + ' ' + (CASE WHEN pntStrad.numero_civico IS NULL THEN '' ELSE pntStrad.numero_civico END)
+ (CASE WHEN pntStrad.esponente_civico IS NULL THEN '' ELSE '/'+pntStrad.esponente_civico END) + ', ' +
(CASE WHEN cap.codice IS NULL THEN '' ELSE cap.codice END)+ ' '+ (CASE WHEN comune.comune IS NULL THEN '' ELSE comune.comune END)
END),'') SedeLegale,
CAST(cliente.data_cliente_dal AS DATE) dataClienteDal,
CAST(cliente.dt_inserimento AS DATE) dataInserimento,
CAST(cliente.dt_modifica AS DATE) dataModifica,
COALESCE(cliente.nome,'') nome,
COALESCE(cliente.cognome,'') cognome,
CAST(COALESCE((SELECT DISTINCT 1 FROM e2_com_contratti k
JOIN e2_com_prestazioni p ON p.fk_e2_com_contratto = k.id
WHERE k.fk_e2_com_cliente = cliente.id
AND k.fk_e0_prof_nodo = cliDett.fk_e0_prof_nodo
AND p.dt_scadenza >= GETDATE()),0) AS BIT) flagAttivo,
CAST(cliente.fl_piva_duplicata AS BIT) flagPartIvaDupl,
CAST(cliente.fl_spacement_firma AS BIT) flagSpacement,
CAST(cliente.fl_importante AS BIT) flagImportante,
CAST(cliente.fl_mail_fattura AS BIT) flagMail,
CAST(COALESCE(STUFF((SELECT '; '+ COALESCE(mail.email,'')
FROM (
SELECT DISTINCT c.id,n.id nodo,c.mail_cliente email FROM e2_com_clienti c
JOIN e0_prof_nodi n ON n.fk_e0_prof_tipo_nodo = 1
WHERE c.mail_cliente <> ' '
UNION
SELECT DISTINCT c.id,d.fk_e0_prof_nodo nodo,d.mail_fattura email FROM e2_com_clienti c
JOIN e2_com_contab_clienti_dett d ON d.fk_e2_com_cliente = c.id
WHERE d.mail_fattura <> ' '
UNION
SELECT DISTINCT c.id,w.fk_e0_prof_nodo nodo,w.indirizzo_mail email FROM e2_com_clienti c
JOIN e2_amm_wizard_fatture w ON w.fk_e2_com_clienti = c.id
WHERE w.indirizzo_mail <> ' '
) mail
WHERE mail.id = cliente.id
AND mail.nodo = cliDett.fk_e0_prof_nodo
FOR XML PATH ('')),1,2,''),'') AS VARCHAR(MAX)) mail,
CAST(cliente.fl_fax_fattura AS BIT) flagFax,
COALESCE(cliente.fax_fattura,'') fax,
CAST(cliente.fl_postalizzazione AS BIT) flagPosta,
CAST(cliente.fl_sogg_ritenuta AS BIT) flagRitenuta,
COALESCE(ritenuta.descrizione,'') ritenAcconto,
COALESCE(cliDett.conto_cliente,'') contoCliente,
COALESCE(cliDett.codice_contabilita,'') codiceContabilita,
CAST(COALESCE(cliDett.fl_dichiarazione_intenti,0) AS BIT) flagDicIntenti,
COALESCE(cliDett.numero_dic_int,'') numDicIntenti,
CAST(cliDett.dt_rilascio_dic_int AS DATE) dataRilascioDicIntenti,
CAST(cliDett.dt_decorrenza_dic_int AS DATE) dataDecorDicIntenti,
CAST(cliDett.dt_scadenza_dic_int AS DATE) dataScadDicIntenti,
CAST(COALESCE(cliDett.fl_importante_fatt,0) AS BIT) flagImportanteFatt,
CAST(COALESCE(cliDett.fl_autocertif_f24,0) AS BIT) flagAutoCertF24,
CAST(COALESCE(cliDett.fl_cliente_contabilizzato,0) AS BIT) flagCliContab,
COALESCE(canale.descrizione,'') canale,
COALESCE(grInd.descrizione,'') gruppoInd,
COALESCE(segComm.descrizione,'') segComm,
COALESCE(ateco.descrizione,'') categMerceologica,
COALESCE(cliente.note,'') noteCliente,
CAST(COALESCE(STUFF((SELECT DISTINCT '; ' + COALESCE(g.nome,'')
FROM e2_com_gestori_clienti gc
JOIN e0_decod_gestori g ON g.id = gc.fk_e2_com_gestore
WHERE gc.fk_e2_com_cliente = cliente.id
FOR XML PATH ('')),1,2,''),'') AS VARCHAR(MAX)) gestoreCliente,
CAST(COALESCE(STUFF((SELECT DISTINCT '; ' + COALESCE(ic.codice,'') + ' ('+COALESCE(ic.codice_mandato,'')+')'
FROM e2_com_iban_cliente_dett ic
WHERE ic.fk_e2_com_cont_cliente = cliDett.id
FOR XML PATH ('')),1,2,''),'') AS VARCHAR(MAX)) ibanCliente,
CAST(COALESCE(STUFF((SELECT DISTINCT '; ' + cc.nome + ' - ' + tcc.recapito
FROM e2_com_contatti_clienti cc
JOIN e2_com_tipo_contatti_cliente tcc ON tcc.fk_e2_com_contatto_cliente = cc.id
WHERE cc.fk_e2_com_cliente = cliente.id
FOR XML PATH ('')),1,2,''),'') AS VARCHAR(MAX))riferimentiCliente,
CAST(COALESCE(STUFF((SELECT '; '+ modiPag.descrizione
FROM (
SELECT DISTINCT c.id,w.fk_e0_prof_nodo,mp.descrizione FROM e2_com_clienti c
JOIN e2_amm_wizard_fatture w ON w.fk_e2_com_clienti = c.id
JOIN e0_decod_modi_pagamento mp ON mp.id = w.fk_e0_decod_modo_pagamento
JOIN e2_com_contratti k ON k.fk_e2_com_cliente = c.id AND k.fk_e0_prof_nodo = w.fk_e0_prof_nodo
JOIN e2_com_prestazioni p ON p.fk_e2_com_contratto = k.id AND p.codiceAggregazione = w.codice_aggregazione
WHERE p.dt_scadenza >= GETDATE()) modiPag
WHERE modiPag.id = cliente.id
AND modiPag.fk_e0_prof_nodo = cliDett.fk_e0_prof_nodo
FOR XML PATH ('')),1,2,''),'') AS VARCHAR(MAX)) modoPagamento,
COALESCE(statoCredCliente.descrizione,'') statoCreditoCliente,
COALESCE(iva.descrizione,'') aliquotaIva,
CAST(COALESCE(STUFF((SELECT '; '+ COALESCE(codPA.codUnivoco,'')
FROM (
SELECT c.id,k.fk_e0_prof_nodo,k.cod_destinatario codUnivoco FROM e2_com_clienti c
JOIN e2_com_contratti k ON k.fk_e2_com_cliente = c.id
WHERE k.fk_e0_decod_stato_contratto = '1'
UNION
SELECT c.id,d.fk_e0_prof_nodo,d.cod_destinatario codUnivoco FROM e2_com_clienti c
JOIN e2_com_contab_clienti_dett d ON d.fk_e2_com_cliente = c.id
UNION
SELECT c.id,w.fk_e0_prof_nodo,w.cod_destinatario codUnivoco FROM e2_com_clienti c
JOIN e2_amm_wizard_fatture w ON w.fk_e2_com_clienti = c.id
) codPA
WHERE codPA.id = cliente.id
AND codPA.fk_e0_prof_nodo = cliDett.fk_e0_prof_nodo
FOR XML PATH ('')),1,2,''),'') AS VARCHAR(MAX)) codiceUnivocoPA
FROM e2_com_clienti cliente
JOIN e0_conf_natura_clienti natura ON natura.id = cliente.fk_e0_natura_cliente
LEFT JOIN e2_com_contab_clienti_dett cliDett ON cliDett.fk_e2_com_cliente = cliente.id AND cliDett.fl_cliente = 1
LEFT JOIN e0_prof_nodi azienda ON azienda.id = cliDett.fk_e0_prof_nodo
LEFT JOIN e0_decod_ritenuta ritenuta ON ritenuta.id = cliDett.fk_e0_decod_ritenuta
LEFT JOIN e0_decod_tipi_cliente canale ON canale.id = cliente.fk_e0_decod_tipo_cliente
LEFT JOIN e0_decod_gr_ind_com grInd ON grInd.id = cliente.fk_e0_decod_gp_ind_com
LEFT JOIN e0_decod_segmento_com segComm ON segComm.id = cliente.fk_e0_decod_seg_com
LEFT JOIN e0_decod_codici_ateco ateco ON ateco.id = cliente.fk_e0_decod_codice_ateco
LEFT JOIN e2_com_ubicazioni_clienti sede ON sede.fk_e2_com_cliente = cliente.id AND sede.fl_primario = 1
LEFT JOIN e2_com_punti_stradario pntStrad ON sede.fk_e2_com_pt_stradario = pntStrad.id
LEFT JOIN e0_conf_tipi_via tipoVia ON pntStrad.fk_e0_decod_tipo_via = tipoVia.id
LEFT JOIN e0_conf_comuni_cap cap ON pntStrad.fk_e0_conf_cap_comune = cap.id
LEFT JOIN e0_conf_comuni comune ON cap.fk_e0_conf_comune = comune.codice_catastale
LEFT JOIN e0_conf_viario viario ON pntStrad.fk_e0_decod_viario = viario.id
LEFT JOIN e0_conf_tipi_via tipoVia2 ON viario.fk_e0_decod_tipo_via = tipoVia2.id
LEFT JOIN e0_decod_stati_clienti statoCredCliente ON statoCredCliente.id = cliDett.fk_e0_decod_stato_cliente
LEFT JOIN e0_decod_iva iva ON iva.id = cliDett.fk_e0_decod_iva
WHERE cliente.fl_cliente = 1
谢谢
编辑2:解决方案
经过多次尝试,我们了解问题不是来自视图上的选择,而是来自同一事务中执行的另一个查询,即在此方法之后调用的查询:
dwhExtractionCCPQuery = caricaControlloContrattiQuery(filter);
这个方法调用了一个存储过程,该存储过程仅在此特定模式上被窃听,简而言之,它在最后有一个错位的插入。 卸下插件解决了这个问题!
答案 0 :(得分:3)
经过多次尝试,我们了解问题不是来自视图上的选择,而是来自同一事务中执行的另一个查询,即在此方法之后调用的查询:
dwhExtractionCCPQuery = caricaControlloContrattiQuery(filter);
此方法调用的存储过程仅在此特定架构上出错,简而言之在存储过程结束时存在错位的插入。
我们在步骤中找到了解决方案:
1 - 首先我们确定在同一个@transactional方法中有2个不同的查询,第一个是存储过程的EXEC,第二个是视图上的select
2 - 我们将查询分为两个独立的@transactional方法
3 - 发现它是第一个崩溃的查询
4 - 分析存储过程以找出与其他工作模式的差异
5 - 找到错位的插页
移除插件解决了问题!