Количество транзакций после выполнения указывает на несоответствие количества инструкций BEGIN и COMMIT. Предыдущий счет
Я получаю это исключение о фиксациях и откатах, но не уверен, что именно не так с моей хранимой процедурой. Я прочитал ответы в других таких вопросах и не могу найти, где именно счетчик фиксации запутывается.
Итак, это хранимая процедура, которую я использую:
-- this is a procedure used for the purge utility. This procedure uses the parameters of a date and lets user select
-- if the leads that should be purge must be closed either before, on or since that date.
-- operator: 0-->less 1-->equal 2-->greater
-- @closed: closing date
-- leadscount: returns the count of leads deleted
IF OBJECT_ID ('LEAD_PURGE', 'P') IS NOT NULL
DROP PROCEDURE LEAD_PURGE
go
CREATE PROCEDURE LEAD_PURGE
@purgextns INT,
@leadscount INT OUTPUT
AS
BEGIN
BEGIN TRANSACTION
CREATE TABLE #ASSIGNMENTS_DELETED
(
ID NUMERIC(19, 0)
PRIMARY KEY (ID)
)
CREATE TABLE #MAPRESULTS_DELETED
(
ID NUMERIC(19, 0)
PRIMARY KEY (ID)
)
CREATE TABLE #COMMAND_DELETED
(
ID NUMERIC(19, 0)
PRIMARY KEY (ID)
)
CREATE TABLE #PROGRESS_STATUS_DELETED
(
ID NUMERIC(19, 0)
PRIMARY KEY (ID)
)
CREATE TABLE #DETAILS_DELETED
(
ID NUMERIC(19, 0)
PRIMARY KEY (ID)
)
CREATE TABLE #NEEDS_DELETED
(
ID NUMERIC(19, 0)
PRIMARY KEY (ID)
)
insert into #ASSIGNMENTS_DELETED
select SEQID FROM ASSIGNMENT WHERE LEADSEQ IN (SELECT ID FROM PURGE_LEAD);
SELECT @leadscount = (SELECT COUNT(*) FROM PURGE_LEAD);
INSERT INTO #MAPRESULTS_DELETED
SELECT ID FROM MAPRESULT WHERE ASSIGNMENTSEQ IN (SELECT ID FROM #ASSIGNMENTS_DELETED)
INSERT INTO #COMMAND_DELETED
SELECT ID FROM EXECUTERULECOMMAND WHERE MAPRESULTID IN (SELECT ID FROM #MAPRESULTS_DELETED)
INSERT INTO #PROGRESS_STATUS_DELETED
SELECT PROGRESS_STATUS_ID FROM COMMAND WHERE ID IN (SELECT ID FROM #COMMAND_DELETED)
INSERT INTO #DETAILS_DELETED
SELECT DETAILID FROM LEAD WHERE SEQID IN (SELECT ID FROM PURGE_LEAD)
INSERT INTO #NEEDS_DELETED
SELECT NEEDSID FROM LEAD WHERE SEQID IN (SELECT ID FROM PURGE_LEAD)
DELETE FROM PROGRESS_STATUS WHERE ID IN (SELECT ID FROM #PROGRESS_STATUS_DELETED)
DELETE FROM EXECUTERULECOMMAND WHERE ID IN (SELECT ID FROM #COMMAND_DELETED)
DELETE FROM COMMAND WHERE ID IN (SELECT ID FROM #COMMAND_DELETED)
DELETE FROM SIMPLECONDITIONAL WHERE RESULT IN (SELECT ID FROM #MAPRESULTS_DELETED)
DELETE FROM MAPPREDICATE WHERE ROWBP IN (SELECT ID FROM MAPROW WHERE RESULT IN (SELECT ID FROM #MAPRESULTS_DELETED))
DELETE FROM MAPROW WHERE RESULT IN (SELECT ID FROM #MAPRESULTS_DELETED)
DELETE FROM MAPRESULT WHERE ID IN (SELECT ID FROM #MAPRESULTS_DELETED)
DELETE FROM ASSIGNMENTATTACHMENTS WHERE ASSIGNMENTSEQ IN (SELECT ID FROM #ASSIGNMENTS_DELETED)
DELETE FROM LEADOBSERVER WHERE ASSIGNSEQ IN (SELECT ID FROM #ASSIGNMENTS_DELETED)
DELETE FROM MAPDESTINATIONS WHERE SUGGESTEDASSIGNID IN
(SELECT ID FROM SUGGESTEDASSIGNMENT WHERE ASSIGNMENT_SEQID IN (SELECT ID FROM #ASSIGNMENTS_DELETED))
DELETE FROM SUGGESTEDASSIGNMENT WHERE ASSIGNMENT_SEQID IN (SELECT ID FROM #ASSIGNMENTS_DELETED)
DELETE FROM PRODUCTINTEREST WHERE LEADSEQ IN (SELECT ID FROM PURGE_LEAD)
CREATE TABLE #SALE_DELETED_EX
(
ID NUMERIC(19, 0)
PRIMARY KEY (ID)
)
INSERT into #SALE_DELETED_EX SELECT SALEEXSEQ FROM SALE WHERE SEQID IN (SELECT SALEID FROM LEADSALES WHERE LEADID IN (SELECT ID FROM PURGE_LEAD))
DELETE FROM SALE WHERE SEQID IN (SELECT SALEID FROM LEADSALES WHERE LEADID IN (SELECT ID FROM PURGE_LEAD))
DELETE FROM SALEEXTENSIONS WHERE
SEQID IN (SELECT ID FROM #SALE_DELETED_EX)
DELETE FROM LEADSALES WHERE LEADID IN (SELECT ID FROM PURGE_LEAD)
DELETE FROM NOTES WHERE OBJECTID IN (SELECT ID FROM #NEEDS_DELETED) OR OBJECTID IN (SELECT ID FROM #DETAILS_DELETED)
DELETE FROM HISTORYRECORD WHERE OBJECTID IN (SELECT ID FROM #DETAILS_DELETED)
DELETE FROM DETAIL WHERE SEQID IN (SELECT ID FROM #NEEDS_DELETED UNION SELECT ID FROM #DETAILS_DELETED)
DELETE FROM MESSAGES WHERE PROVIDERID IN (SELECT ID FROM PURGE_LEAD)
DELETE FROM ASSIGNMENT WHERE LEADSEQ IN (SELECT ID FROM PURGE_LEAD)
DELETE FROM LEAD WHERE SEQID IN (SELECT ID FROM PURGE_LEAD)
CREATE TABLE #PURGE_LEAD_E
(
ID NUMERIC(19, 0)
PRIMARY KEY (ID)
)
INSERT into #PURGE_LEAD_E Select SEQID FROM LEADEXTENSIONS WHERE
SEQID NOT IN (SELECT LEADEXSEQ FROM LEAD)
if @purgextns = 1 begin
DELETE FROM LEADEXTENSIONS WHERE
SEQID IN (SELECT ID FROM PURGE_LEAD_E)
end
DELETE FROM PURGE_LEAD;
DROP TABLE #ASSIGNMENTS_DELETED
DROP TABLE #MAPRESULTS_DELETED
DROP TABLE #COMMAND_DELETED
DROP TABLE #PROGRESS_STATUS_DELETED
DROP TABLE #DETAILS_DELETED
DROP TABLE #NEEDS_DELETED
DROP TABLE #PURGE_LEAD_E
DROP TABLE #SALE_DELETED_EX
COMMIT
END
go
теперь я вызываю эту процедуру в следующем коде:
try {
c = new ConnectionHelper().getConnection();
String sql = "";
if (shouldPurgeExtns) {
progressModel.makeProgress("progress.deleting.dependents");
purgeMultiselect(c, LEAD, isMSSQL);
}
sql = "{CALL " + TOPLinkManager.getSchemaPrefix()
+ "LEAD_PURGE (?,?)}";
cs = c.prepareCall(sql);
cs.setInt(1, shouldPurgeExtns ? 0 : 1);
cs.registerOutParameter(2, java.sql.Types.INTEGER);
cs.executeUpdate();
int rowcount = cs.getInt(2);
cs.close();
progressModel.makeProgress("progress.recording.history");
recordHistory(c, isMSSQL, LEAD, DateTypeDecorator.CLOSED, date,
rowcount);
done(progressModel);
c.close();
return true;
} catch (Exception e) {
Logs.main.error("Error Purging Leads", e);
throw new Exception(e.getMessage());
}
и я получаю исключение на линии, которая говорит int rowcount = cs.getInt(2);
в Исключение составляет:
com.microsoft.sqlserver.jdbc.SQLServerException: Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:196)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1454)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.processResults(SQLServerStatement.java:1083)
at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getOutParameter(SQLServerCallableStatement.java:112)
at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getterGetParam(SQLServerCallableStatement.java:387)
пожалуйста, помогите мне. по ком.Microsoft.от SQLServer.интерфейс jdbc.Класса sqlservercallablestatement.getValue (SQLServerCallableStatement.java: 393) по ком.Microsoft.от SQLServer.интерфейс jdbc.Класса sqlservercallablestatement.getInt (SQLServerCallableStatement.java: 437) на marketsoft.инструменты.очистка.PurgeUtils.PurgeLeads (PurgeUtils.java: 283)
EDIT:
как я сам ответил на этот вопрос... Я хотел бы изменить вопрос теперь немного.
почему в методе execute не было исключения???
5 ответов
ваша фиксация не попадает, вероятно, из-за ошибки. Транзакция не будет откатываться автоматически
лучший способ (и лучшая практика) - добавить некоторую обработку ошибок SQL
CREATE PROCEDURE LEAD_PURGE
@purgextns INT,
@leadscount INT OUTPUT
AS
SET NOCOUNT, XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION
CREATE TABLE #ASSIGNMENTS_DELETED
(
ID NUMERIC(19, 0)
PRIMARY KEY (ID)
)
...
DROP TABLE #SALE_DELETED_EX
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION
RAISERROR ('it broke', 16, 1)
END CATCH
go
для получения более подробной информации о том, что происходит здесь, см. Мой ответ здесь вложенные хранимые процедуры, содержащие шаблон отката try CATCH?
Примечание: вам не нужно отбрасывать временные таблицы, поскольку они выходят за рамки, когда хранимая процедура выходы
попробуйте добавить в начале процедуры
SET XACT_ABORT ON
или
оберните свои заявления с
begin try
BEGIN TRANSACTION
Your TSQL code
COMMIT
end try
begin catch
ROLLBACK
RAISERROR('Gotcha!', 16, 1)
end catch
чтобы проверить, сколько незафиксированных BEGIN TRAN
открывается тест @@TRANCOUNT
системная переменная
обычно это происходит, когда транзакция запущена и либо она не зафиксирована, либо не откатывается.
в случае возникновения ошибки в хранимой процедуре это может заблокировать таблицы базы данных, поскольку транзакция не завершена из - за некоторых ошибок во время выполнения при отсутствии обработки исключений Вы можете использовать обработку исключений, как показано ниже. УСТАНОВИТЬ XACT_ABORT
SET XACT_ABORT ON
SET NoCount ON
Begin Try
BEGIN TRANSACTION
//Insert ,update queries
COMMIT
End Try
Begin Catch
ROLLBACK
End Catch
Извините, Ребята! Спасибо за все ваши усилия, в конце концов, это была очень маленькая ошибка с моей стороны в хранимой процедуре:
смотреть на строку:
if @purgextns = 1 begin
DELETE FROM LEADEXTENSIONS WHERE
SEQID IN (SELECT ID FROM PURGE_LEAD_E)
end
Он должен быть!--1-->
все ваши ответы помогли мне получить другую перспективу развития процедуры магазина. Большое спасибо!
Как именно переменная @leadscount содержит количество удаленных выводов?
Это единственное место, где я вижу, что он используется:
SELECT @leadscount = (выберите COUNT (*) из PURGE_LEAD);
во всяком случае, чтобы проверить это, почему бы вам не запустить вышеуказанный код вне контекста транзакции?
Если вам действительно нужно, чтобы он был внутри транзакции, попробуйте загрузить значение в переменную таблицы (создайте таблицу только с одним столбцом). Поскольку они не участвуют в транзакциях, вы можете проверить, является ли транзакция вашей реальной проблемой.