mirror of
https://github.com/1C-Company/v8-code-style.git
synced 2024-11-28 09:33:06 +02:00
Нарушена схема работы с транзакциями (#922)
This commit is contained in:
parent
5b2036df3a
commit
ccf546d290
10
CHANGELOG.md
10
CHANGELOG.md
@ -25,6 +25,16 @@
|
||||
|
||||
#### Код модулей
|
||||
- Избыточное обращение внутри модуля через его имя или псевдоним ЭтотОбъект (к методу, свойству или реквизиту)
|
||||
- Проверка нарушения схемы работы с транзакциями связанной с фиксацией транзакции:
|
||||
1. Вызов "ЗафиксироватьТранзакцию()" находится вне конструкции "Попытка... Исключение"
|
||||
2. Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ЗафиксироватьТранзакцию()"
|
||||
3. Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ОтменитьТранзакцию()"
|
||||
4. Mежду "ЗафиксироватьТранзакцию()" и "Исключение" есть исполняемый код, который может вызвать исключение
|
||||
- Проверка нарушения схемы работы с транзакциями связанной с отменой транзакции:
|
||||
1. Вызов "ОтменитьТранзакцию()" находится вне конструкции "Попытка... Исключение"
|
||||
2. Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ОтменитьТранзакцию()"
|
||||
3. Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ЗафиксироватьТранзакцию()"
|
||||
4. Mежду "Исключение" и "ОтменитьТранзакцию()" есть исполняемый код, который может вызвать исключение
|
||||
- Отсутствует удаление временного файла после использования.
|
||||
|
||||
#### Запросы
|
||||
|
@ -0,0 +1,41 @@
|
||||
# The scheme of working with transactions is broken
|
||||
|
||||
Commit transaction must be in a try-catch,
|
||||
there should be no executable code between commit transaction and exception,
|
||||
there is no begin transaction for commit transaction,
|
||||
there is no rollback transaction for begin transaction.
|
||||
|
||||
## Noncompliant Code Example
|
||||
|
||||
```bsl
|
||||
BeginTransaction();
|
||||
CommitTransaction();
|
||||
Try
|
||||
// ...
|
||||
Except
|
||||
// ...
|
||||
RollbackTransaction();
|
||||
// ...
|
||||
Raise;
|
||||
EndTry;
|
||||
```
|
||||
|
||||
## Compliant Solution
|
||||
|
||||
```bsl
|
||||
BeginTransaction();
|
||||
Try
|
||||
// ...
|
||||
CommitTransaction();
|
||||
Except
|
||||
// ...
|
||||
RollbackTransaction();
|
||||
// ...
|
||||
Raise;
|
||||
EndTry;
|
||||
```
|
||||
|
||||
## See
|
||||
|
||||
- [Catching exceptions in code](https://support.1ci.com/hc/en-us/articles/360011002440-Catching-exceptions-in-code)
|
||||
- [Transactions: rules of use](https://support.1ci.com/hc/en-us/articles/360011121239-Transactions-rules-of-use)
|
@ -0,0 +1,40 @@
|
||||
# The scheme of working with transactions is broken
|
||||
|
||||
Rollback transaction must be in a try-catch,
|
||||
there should be no executable code between exception and rollback transaction,
|
||||
there is no begin transaction for rollback transaction,
|
||||
there is no commit transaction for begin transaction.
|
||||
|
||||
## Noncompliant Code Example
|
||||
|
||||
```bsl
|
||||
BeginTransaction();
|
||||
Try
|
||||
// ...
|
||||
CommitTransaction();
|
||||
Except
|
||||
// ...
|
||||
Raise;
|
||||
EndTry;
|
||||
RollbackTransaction();
|
||||
```
|
||||
|
||||
## Compliant Solution
|
||||
|
||||
```bsl
|
||||
BeginTransaction();
|
||||
Try
|
||||
// ...
|
||||
CommitTransaction();
|
||||
Except
|
||||
// ...
|
||||
RollbackTransaction();
|
||||
// ...
|
||||
Raise;
|
||||
EndTry;
|
||||
```
|
||||
|
||||
## See
|
||||
|
||||
- [Catching exceptions in code](https://support.1ci.com/hc/en-us/articles/360011002440-Catching-exceptions-in-code)
|
||||
- [Transactions: rules of use](https://support.1ci.com/hc/en-us/articles/360011121239-Transactions-rules-of-use)
|
@ -0,0 +1,41 @@
|
||||
# Проверка нарушения схемы работы с транзакциями
|
||||
|
||||
Вызов "ЗафиксироватьТранзакцию()" находится вне конструкции "Попытка... Исключение"
|
||||
Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ЗафиксироватьТранзакцию()"
|
||||
Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ОтменитьТранзакцию()"
|
||||
Mежду "ЗафиксироватьТранзакцию()" и "Исключение" есть исполняемый код, который может вызвать исключение
|
||||
|
||||
## Неправильно
|
||||
|
||||
```bsl
|
||||
НачатьТранзакцию();
|
||||
ЗафиксироватьТранзакцию();
|
||||
Попытка
|
||||
// ...
|
||||
Исключение
|
||||
// ...
|
||||
ОтменитьТранзакцию();
|
||||
// ...
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
```
|
||||
|
||||
## Правильно
|
||||
|
||||
```bsl
|
||||
НачатьТранзакцию();
|
||||
Попытка
|
||||
// ...
|
||||
ЗафиксироватьТранзакцию();
|
||||
Исключение
|
||||
// ...
|
||||
ОтменитьТранзакцию();
|
||||
// ...
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
```
|
||||
|
||||
## См.
|
||||
|
||||
- [Перехват исключений в коде](https://its.1c.ru/db/v8std#content:499:hdoc:3.6)
|
||||
- [Транзакции: правила использования](https://its.1c.ru/db/v8std#content:783:hdoc:1.3)
|
@ -0,0 +1,40 @@
|
||||
# Проверка нарушения схемы работы с транзакциями
|
||||
|
||||
Вызов "ОтменитьТранзакцию()" находится вне конструкции "Попытка... Исключение"
|
||||
Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ОтменитьТранзакцию()"
|
||||
Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ЗафиксироватьТранзакцию()"
|
||||
Mежду "Исключение" и "ОтменитьТранзакцию()" есть исполняемый код, который может вызвать исключение
|
||||
|
||||
## Неправильно
|
||||
|
||||
```bsl
|
||||
НачатьТранзакцию();
|
||||
Попытка
|
||||
// ...
|
||||
ЗафиксироватьТранзакцию();
|
||||
Исключение
|
||||
// ...
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
ОтменитьТранзакцию();
|
||||
```
|
||||
|
||||
## Правильно
|
||||
|
||||
```bsl
|
||||
НачатьТранзакцию();
|
||||
Попытка
|
||||
// ...
|
||||
ЗафиксироватьТранзакцию();
|
||||
Исключение
|
||||
// ...
|
||||
ОтменитьТранзакцию();
|
||||
// ...
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
```
|
||||
|
||||
## См.
|
||||
|
||||
- [Перехват исключений в коде](https://its.1c.ru/db/v8std#content:499:hdoc:3.6)
|
||||
- [Транзакции: правила использования](https://its.1c.ru/db/v8std#content:783:hdoc:1.3)
|
@ -259,6 +259,14 @@
|
||||
category="com.e1c.v8codestyle.bsl"
|
||||
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.ManagerModuleNamedSelfReferenceCheck">
|
||||
</check>
|
||||
<check
|
||||
category="com.e1c.v8codestyle.bsl"
|
||||
class="com.e1c.v8codestyle.bsl.check.CommitTransactionCheck">
|
||||
</check>
|
||||
<check
|
||||
category="com.e1c.v8codestyle.bsl"
|
||||
class="com.e1c.v8codestyle.bsl.check.RollbackTransactionCheck">
|
||||
</check>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.core.runtime.preferences">
|
||||
|
@ -0,0 +1,222 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2022, 1C-Soft LLC and others.
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* 1C-Soft LLC - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.e1c.v8codestyle.bsl.check;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.EcoreUtil2;
|
||||
|
||||
import com._1c.g5.v8.dt.bsl.model.BslPackage;
|
||||
import com._1c.g5.v8.dt.bsl.model.Conditional;
|
||||
import com._1c.g5.v8.dt.bsl.model.EmptyStatement;
|
||||
import com._1c.g5.v8.dt.bsl.model.IfStatement;
|
||||
import com._1c.g5.v8.dt.bsl.model.Invocation;
|
||||
import com._1c.g5.v8.dt.bsl.model.LoopStatement;
|
||||
import com._1c.g5.v8.dt.bsl.model.PreprocessorItem;
|
||||
import com._1c.g5.v8.dt.bsl.model.PreprocessorItemStatements;
|
||||
import com._1c.g5.v8.dt.bsl.model.RegionPreprocessor;
|
||||
import com._1c.g5.v8.dt.bsl.model.SimpleStatement;
|
||||
import com._1c.g5.v8.dt.bsl.model.Statement;
|
||||
import com._1c.g5.v8.dt.bsl.model.TryExceptStatement;
|
||||
import com.e1c.g5.v8.dt.check.components.BasicCheck;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* Common functionality for transaction analysis.
|
||||
*
|
||||
* @author Artem Iliukhin
|
||||
*/
|
||||
abstract class AbstractTransactionCheck
|
||||
extends BasicCheck
|
||||
{
|
||||
|
||||
protected static final String COMMIT_TRANSACTION_RU = "ЗафиксироватьТранзакцию"; //$NON-NLS-1$
|
||||
protected static final String COMMIT_TRANSACTION = "CommitTransaction"; //$NON-NLS-1$
|
||||
protected static final String BEGIN_TRANSACTION = "BeginTransaction"; //$NON-NLS-1$
|
||||
protected static final String BEGIN_TRANSACTION_RU = "НачатьТранзакцию"; //$NON-NLS-1$
|
||||
protected static final String ROLLBACK_TRANSACTION = "RollbackTransaction"; //$NON-NLS-1$
|
||||
protected static final String ROLLBACK_TRANSACTION_RU = "ОтменитьТранзакцию"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Checks if is rollback statement.
|
||||
*
|
||||
* @param statement the statement
|
||||
* @return true, if is rollback statement
|
||||
*/
|
||||
protected final boolean isRollbackStatement(Statement statement)
|
||||
{
|
||||
if (statement instanceof SimpleStatement && ((SimpleStatement)statement).getLeft() instanceof Invocation)
|
||||
{
|
||||
Invocation invocation = (Invocation)((SimpleStatement)statement).getLeft();
|
||||
String invocName = invocation.getMethodAccess().getName();
|
||||
if (ROLLBACK_TRANSACTION_RU.equals(invocName) || ROLLBACK_TRANSACTION.equals(invocName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the all statements.
|
||||
*
|
||||
* @param statements the statements
|
||||
* @return the all statements, cannot return {@code null}.
|
||||
*/
|
||||
protected final List<Statement> getAllStatement(List<Statement> statements)
|
||||
{
|
||||
List<Statement> res = Lists.newArrayList(statements);
|
||||
|
||||
Statement lastStatement = getLastStatement(res);
|
||||
while (lastStatement instanceof RegionPreprocessor)
|
||||
{
|
||||
RegionPreprocessor regionPreprocessorStatement = (RegionPreprocessor)lastStatement;
|
||||
PreprocessorItem item = regionPreprocessorStatement.getItem();
|
||||
if (item instanceof PreprocessorItemStatements && item.hasStatements())
|
||||
{
|
||||
PreprocessorItemStatements itemStatements = (PreprocessorItemStatements)item;
|
||||
res.addAll(itemStatements.getStatements());
|
||||
}
|
||||
item = regionPreprocessorStatement.getItemAfter();
|
||||
if (item instanceof PreprocessorItemStatements && item.hasStatements())
|
||||
{
|
||||
PreprocessorItemStatements itemStatements = (PreprocessorItemStatements)item;
|
||||
res.addAll(itemStatements.getStatements());
|
||||
}
|
||||
lastStatement = getLastStatement(res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last statement or {@code null} if not found.
|
||||
*
|
||||
* @param statements the statements
|
||||
* @return the last statement, can return {@code null}.
|
||||
*/
|
||||
protected final Statement getLastStatement(List<Statement> statements)
|
||||
{
|
||||
int index = statements.size() - 1;
|
||||
while (index >= 0 && statements.get(index) instanceof EmptyStatement)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
if (index >= 0)
|
||||
{
|
||||
return statements.get(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next statement or {@code null} if not found.
|
||||
*
|
||||
* @param statement the statement
|
||||
* @return the next statement, can return {@code null}
|
||||
*/
|
||||
protected final Statement getNextStatement(Statement statement)
|
||||
{
|
||||
Iterator<EObject> it = EcoreUtil2.getAllContainers(statement).iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
EObject container = it.next();
|
||||
List<Statement> st = null;
|
||||
if (container instanceof LoopStatement)
|
||||
{
|
||||
st = ((LoopStatement)container).getStatements();
|
||||
}
|
||||
else if (container instanceof Conditional)
|
||||
{
|
||||
st = ((Conditional)container).getStatements();
|
||||
}
|
||||
else if (container instanceof IfStatement)
|
||||
{
|
||||
st = ((IfStatement)container).getElseStatements();
|
||||
}
|
||||
else if (container instanceof TryExceptStatement)
|
||||
{
|
||||
st = getStatementsFromContainer((TryExceptStatement)container);
|
||||
}
|
||||
else if (container instanceof PreprocessorItemStatements)
|
||||
{
|
||||
st = ((PreprocessorItemStatements)container).getStatements();
|
||||
}
|
||||
else
|
||||
{
|
||||
st = getStatementsFromContainer(container);
|
||||
}
|
||||
if (st != null)
|
||||
{
|
||||
int index = st.indexOf(statement);
|
||||
if (index != -1 && index + 1 < st.size())
|
||||
{
|
||||
return st.get(index + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the statement from invoc or {@code null} if not found.
|
||||
*
|
||||
* @param invocation the invocation
|
||||
* @return the statement from invoc, can return {@code null}
|
||||
*/
|
||||
protected final Statement getStatementFromInvoc(Invocation invocation)
|
||||
{
|
||||
EObject container = invocation.eContainer();
|
||||
while (!(container instanceof Statement))
|
||||
{
|
||||
container = container.eContainer();
|
||||
}
|
||||
return container instanceof Statement ? (Statement)container : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is commit statement.
|
||||
*
|
||||
* @param statement the statement
|
||||
* @return true, if is commit statement
|
||||
*/
|
||||
protected final boolean isCommitStatement(Statement statement)
|
||||
{
|
||||
if (statement instanceof SimpleStatement && ((SimpleStatement)statement).getLeft() instanceof Invocation)
|
||||
{
|
||||
Invocation invocation = (Invocation)((SimpleStatement)statement).getLeft();
|
||||
String invocName = invocation.getMethodAccess().getName();
|
||||
if (COMMIT_TRANSACTION_RU.equals(invocName) || COMMIT_TRANSACTION.equals(invocName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<Statement> getStatementsFromContainer(TryExceptStatement container)
|
||||
{
|
||||
List<Statement> res = Lists.newArrayList();
|
||||
res.addAll(container.getTryStatements());
|
||||
res.addAll(container.getExceptStatements());
|
||||
return res;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Statement> getStatementsFromContainer(EObject container)
|
||||
{
|
||||
Object obj = container.eGet(BslPackage.Literals.BLOCK__STATEMENTS);
|
||||
return obj instanceof List ? (List<Statement>)obj : null;
|
||||
}
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2022, 1C-Soft LLC and others.
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* 1C-Soft LLC - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.e1c.v8codestyle.bsl.check;
|
||||
|
||||
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.INVOCATION;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.xtext.EcoreUtil2;
|
||||
|
||||
import com._1c.g5.v8.dt.bsl.model.FeatureAccess;
|
||||
import com._1c.g5.v8.dt.bsl.model.Invocation;
|
||||
import com._1c.g5.v8.dt.bsl.model.Method;
|
||||
import com._1c.g5.v8.dt.bsl.model.Statement;
|
||||
import com._1c.g5.v8.dt.bsl.model.StaticFeatureAccess;
|
||||
import com._1c.g5.v8.dt.bsl.model.TryExceptStatement;
|
||||
import com.e1c.g5.v8.dt.check.CheckComplexity;
|
||||
import com.e1c.g5.v8.dt.check.ICheckParameters;
|
||||
import com.e1c.g5.v8.dt.check.settings.IssueSeverity;
|
||||
import com.e1c.g5.v8.dt.check.settings.IssueType;
|
||||
|
||||
/**
|
||||
* Commit transaction must be in a try-catch,
|
||||
* there should be no executable code between commit transaction and exception,
|
||||
* there is no begin transaction for commit transaction,
|
||||
* there is no rollback transaction for begin transaction.
|
||||
*
|
||||
* @author Artem Iliukhin
|
||||
*/
|
||||
public final class CommitTransactionCheck
|
||||
extends AbstractTransactionCheck
|
||||
{
|
||||
|
||||
private static final String CHECK_ID = "commit-transaction"; //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public String getCheckId()
|
||||
{
|
||||
return CHECK_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureCheck(CheckConfigurer builder)
|
||||
{
|
||||
builder.title(Messages.CommitTransactionCheck_Transactions_is_broken)
|
||||
.description(Messages.CommitTransactionCheck_Transactions_is_broken_des)
|
||||
.complexity(CheckComplexity.NORMAL)
|
||||
.severity(IssueSeverity.MINOR)
|
||||
.issueType(IssueType.WARNING)
|
||||
.disable()
|
||||
//.extension(new StandardCheckExtension(getCheckId(), BslPlugin.PLUGIN_ID))
|
||||
.module()
|
||||
.checkedObjectType(INVOCATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
|
||||
IProgressMonitor monitor)
|
||||
{
|
||||
Invocation inv = (Invocation)object;
|
||||
FeatureAccess featureAccess = inv.getMethodAccess();
|
||||
if (featureAccess instanceof StaticFeatureAccess)
|
||||
{
|
||||
String nameFeature = featureAccess.getName();
|
||||
if (!(COMMIT_TRANSACTION_RU.equalsIgnoreCase(nameFeature)
|
||||
|| COMMIT_TRANSACTION.equalsIgnoreCase(nameFeature)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TryExceptStatement tryExceptStatement = EcoreUtil2.getContainerOfType(inv, TryExceptStatement.class);
|
||||
if (tryExceptStatement == null)
|
||||
{
|
||||
resultAceptor.addIssue(Messages.CommitTransactionCheck_Commit_transaction_must_be_in_try_catch, inv);
|
||||
}
|
||||
|
||||
if (monitor.isCanceled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Method method = EcoreUtil2.getContainerOfType(inv, Method.class);
|
||||
if (method == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Invocation> invocations = EcoreUtil2.getAllContentsOfType(method, Invocation.class);
|
||||
for (Invocation invocation : invocations)
|
||||
{
|
||||
String invocName = invocation.getMethodAccess().getName();
|
||||
if (BEGIN_TRANSACTION_RU.equals(invocName) || BEGIN_TRANSACTION.equals(invocName))
|
||||
{
|
||||
if (monitor.isCanceled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Statement statement = getStatementFromInvoc(invocation);
|
||||
Statement nextStatement = null;
|
||||
if (statement != null)
|
||||
{
|
||||
nextStatement = getNextStatement(statement);
|
||||
}
|
||||
if (nextStatement instanceof TryExceptStatement)
|
||||
{
|
||||
anlyseTryExcept(invocation, (TryExceptStatement)nextStatement, resultAceptor);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (COMMIT_TRANSACTION_RU.equals(invocName) || COMMIT_TRANSACTION.equals(invocName))
|
||||
{
|
||||
resultAceptor.addIssue(Messages.CommitTransactionCheck_No_begin_transaction_for_commit_transaction,
|
||||
invocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void anlyseTryExcept(Invocation beginTrans, TryExceptStatement tryExceptStatement,
|
||||
ResultAcceptor resultAceptor)
|
||||
{
|
||||
if (tryExceptStatement.getExceptStatements().isEmpty())
|
||||
{
|
||||
resultAceptor.addIssue(Messages.CommitTransactionCheck_Transaction_contains_empty_except,
|
||||
tryExceptStatement);
|
||||
}
|
||||
|
||||
List<Statement> tryStatements = getAllStatement(tryExceptStatement.getTryStatements());
|
||||
if (!tryStatements.isEmpty())
|
||||
{
|
||||
analyseTryPart(tryStatements, resultAceptor);
|
||||
}
|
||||
|
||||
List<Statement> exceptStatement = getAllStatement(tryExceptStatement.getExceptStatements());
|
||||
if (!exceptStatement.isEmpty())
|
||||
{
|
||||
analyseExceptPart(beginTrans, exceptStatement, resultAceptor);
|
||||
}
|
||||
}
|
||||
|
||||
private void analyseExceptPart(Invocation beginTrans, List<Statement> exceptStatement, ResultAcceptor resultAceptor)
|
||||
{
|
||||
boolean invocThereIs = false;
|
||||
for (Statement statement : exceptStatement)
|
||||
{
|
||||
if (isRollbackStatement(statement))
|
||||
{
|
||||
invocThereIs = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!invocThereIs)
|
||||
{
|
||||
resultAceptor.addIssue(Messages.CommitTransactionCheck_No_rollback_transaction_for_begin_transaction,
|
||||
beginTrans);
|
||||
}
|
||||
}
|
||||
|
||||
private void analyseTryPart(List<Statement> tryStatements,
|
||||
ResultAcceptor resultAceptor)
|
||||
{
|
||||
boolean invocThereIs = false;
|
||||
for (Statement statement : tryStatements)
|
||||
{
|
||||
if (isCommitStatement(statement))
|
||||
{
|
||||
invocThereIs = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (invocThereIs)
|
||||
{
|
||||
Statement lastStatement = getLastStatement(tryStatements);
|
||||
if (!isCommitStatement(lastStatement))
|
||||
{
|
||||
resultAceptor.addIssue(
|
||||
Messages.CommitTransactionCheck_Should_be_no_executable_code_between_commit_and_exception,
|
||||
lastStatement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -46,6 +46,26 @@ final class Messages
|
||||
public static String ChangeAndValidateInsteadOfAroundCheck_Use_ChangeAndValidate_instead_of_Around;
|
||||
public static String ChangeAndValidateInsteadOfAroundCheck_title;
|
||||
|
||||
public static String CommitTransactionCheck_Commit_transaction_must_be_in_try_catch;
|
||||
|
||||
public static String CommitTransactionCheck_No_begin_transaction_for_commit_transaction;
|
||||
|
||||
public static String RollbackTransactionCheck_No_begin_transaction_for_rollback_transaction;
|
||||
|
||||
public static String RollbackTransactionCheck_No_commit_transaction_for_begin_transaction;
|
||||
|
||||
public static String CommitTransactionCheck_No_rollback_transaction_for_begin_transaction;
|
||||
|
||||
public static String CommitTransactionCheck_Should_be_no_executable_code_between_commit_and_exception;
|
||||
|
||||
public static String RollbackTransactionCheck_Should_be_no_executable_code_between_exception_and_rollback;
|
||||
|
||||
public static String CommitTransactionCheck_Transaction_contains_empty_except;
|
||||
|
||||
public static String CommitTransactionCheck_Transactions_is_broken;
|
||||
|
||||
public static String CommitTransactionCheck_Transactions_is_broken_des;
|
||||
|
||||
public static String CommonModuleNamedSelfReferenceCheck_description;
|
||||
|
||||
public static String CommonModuleNamedSelfReferenceCheck_issue;
|
||||
@ -167,6 +187,12 @@ final class Messages
|
||||
|
||||
public static String RegionEmptyCheck_title;
|
||||
|
||||
public static String RollbackTransactionCheck_Rollback_transaction_must_be_in_try_catch;
|
||||
|
||||
public static String RollbackTransactionCheck_Transactions_is_broken;
|
||||
|
||||
public static String RollbackTransactionCheck_Transactions_is_broken_des;
|
||||
|
||||
public static String UseNonRecommendedMethods_description;
|
||||
|
||||
public static String UseNonRecommendedMethods_message;
|
||||
|
@ -0,0 +1,192 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2022, 1C-Soft LLC and others.
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* 1C-Soft LLC - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.e1c.v8codestyle.bsl.check;
|
||||
|
||||
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.INVOCATION;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.xtext.EcoreUtil2;
|
||||
|
||||
import com._1c.g5.v8.dt.bsl.model.FeatureAccess;
|
||||
import com._1c.g5.v8.dt.bsl.model.Invocation;
|
||||
import com._1c.g5.v8.dt.bsl.model.Method;
|
||||
import com._1c.g5.v8.dt.bsl.model.Statement;
|
||||
import com._1c.g5.v8.dt.bsl.model.StaticFeatureAccess;
|
||||
import com._1c.g5.v8.dt.bsl.model.TryExceptStatement;
|
||||
import com.e1c.g5.v8.dt.check.CheckComplexity;
|
||||
import com.e1c.g5.v8.dt.check.ICheckParameters;
|
||||
import com.e1c.g5.v8.dt.check.settings.IssueSeverity;
|
||||
import com.e1c.g5.v8.dt.check.settings.IssueType;
|
||||
|
||||
/**
|
||||
* Rollback transaction must be in a try-catch,
|
||||
* there is no begin transaction for rollback transaction,
|
||||
* there should be no executable code between exception and rollback transaction,
|
||||
* there is no commit transaction for begin transaction.
|
||||
*
|
||||
* @author Artem Iliukhin
|
||||
*/
|
||||
public final class RollbackTransactionCheck
|
||||
extends AbstractTransactionCheck
|
||||
{
|
||||
|
||||
private static final String CHECK_ID = "rollback-transaction"; //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public String getCheckId()
|
||||
{
|
||||
return CHECK_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureCheck(CheckConfigurer builder)
|
||||
{
|
||||
builder.title(Messages.RollbackTransactionCheck_Transactions_is_broken)
|
||||
.description(Messages.RollbackTransactionCheck_Transactions_is_broken_des)
|
||||
.complexity(CheckComplexity.NORMAL)
|
||||
.severity(IssueSeverity.MINOR)
|
||||
.issueType(IssueType.WARNING)
|
||||
.disable()
|
||||
//.extension(new StandardCheckExtension(getCheckId(), BslPlugin.PLUGIN_ID))
|
||||
.module()
|
||||
.checkedObjectType(INVOCATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
|
||||
IProgressMonitor monitor)
|
||||
{
|
||||
Invocation inv = (Invocation)object;
|
||||
FeatureAccess featureAccess = inv.getMethodAccess();
|
||||
if (featureAccess instanceof StaticFeatureAccess)
|
||||
{
|
||||
String nameFeature = featureAccess.getName();
|
||||
if (!(ROLLBACK_TRANSACTION_RU.equalsIgnoreCase(nameFeature)
|
||||
|| ROLLBACK_TRANSACTION.equalsIgnoreCase(nameFeature)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TryExceptStatement tryExceptStatement = EcoreUtil2.getContainerOfType(inv, TryExceptStatement.class);
|
||||
if (tryExceptStatement == null)
|
||||
{
|
||||
resultAceptor.addIssue(Messages.RollbackTransactionCheck_Rollback_transaction_must_be_in_try_catch,
|
||||
inv);
|
||||
}
|
||||
|
||||
if (monitor.isCanceled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Method method = EcoreUtil2.getContainerOfType(inv, Method.class);
|
||||
if (method == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Invocation> invocations = EcoreUtil2.getAllContentsOfType(method, Invocation.class);
|
||||
for (Invocation invocation : invocations)
|
||||
{
|
||||
String invocName = invocation.getMethodAccess().getName();
|
||||
if (BEGIN_TRANSACTION_RU.equals(invocName) || BEGIN_TRANSACTION.equals(invocName))
|
||||
{
|
||||
if (monitor.isCanceled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Statement statement = getStatementFromInvoc(invocation);
|
||||
Statement nextStatement = null;
|
||||
if (statement != null)
|
||||
{
|
||||
nextStatement = getNextStatement(statement);
|
||||
}
|
||||
if (nextStatement instanceof TryExceptStatement)
|
||||
{
|
||||
analyzeTryExcept(invocation, (TryExceptStatement)nextStatement, resultAceptor);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (ROLLBACK_TRANSACTION_RU.equals(invocName) || ROLLBACK_TRANSACTION.equals(invocName))
|
||||
{
|
||||
resultAceptor.addIssue(
|
||||
Messages.RollbackTransactionCheck_No_begin_transaction_for_rollback_transaction, invocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void analyzeTryExcept(Invocation beginTrans, TryExceptStatement tryExceptStatement,
|
||||
ResultAcceptor resultAceptor)
|
||||
{
|
||||
List<Statement> tryStatements = getAllStatement(tryExceptStatement.getTryStatements());
|
||||
if (!tryStatements.isEmpty())
|
||||
{
|
||||
analyzeTryPart(beginTrans, tryStatements, resultAceptor);
|
||||
}
|
||||
|
||||
List<Statement> exceptStatement = getAllStatement(tryExceptStatement.getExceptStatements());
|
||||
if (!exceptStatement.isEmpty())
|
||||
{
|
||||
analyzeExceptPart(exceptStatement, resultAceptor);
|
||||
}
|
||||
}
|
||||
|
||||
private void analyzeTryPart(Invocation beginTrans, List<Statement> tryStatements, ResultAcceptor resultAceptor)
|
||||
{
|
||||
boolean invocThereIs = false;
|
||||
for (Statement statement : tryStatements)
|
||||
{
|
||||
if (isCommitStatement(statement))
|
||||
{
|
||||
invocThereIs = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!invocThereIs)
|
||||
{
|
||||
resultAceptor.addIssue(Messages.RollbackTransactionCheck_No_commit_transaction_for_begin_transaction,
|
||||
beginTrans);
|
||||
}
|
||||
}
|
||||
|
||||
private void analyzeExceptPart(List<Statement> exceptStatement, ResultAcceptor resultAceptor)
|
||||
{
|
||||
boolean invocThereIs = false;
|
||||
for (Statement statement : exceptStatement)
|
||||
{
|
||||
if (isRollbackStatement(statement))
|
||||
{
|
||||
invocThereIs = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (invocThereIs)
|
||||
{
|
||||
Statement firstStatement = exceptStatement.get(0);
|
||||
if (!isRollbackStatement(firstStatement))
|
||||
{
|
||||
resultAceptor.addIssue(
|
||||
Messages.RollbackTransactionCheck_Should_be_no_executable_code_between_exception_and_rollback,
|
||||
firstStatement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -40,6 +40,26 @@ ChangeAndValidateInsteadOfAroundCheck_description = Checks that pragma &ChangeAn
|
||||
|
||||
ChangeAndValidateInsteadOfAroundCheck_title = Use pragma &ChangeAndValidate instead of &Around
|
||||
|
||||
CommitTransactionCheck_Commit_transaction_must_be_in_try_catch=Commit transaction must be in a try-catch
|
||||
|
||||
CommitTransactionCheck_No_begin_transaction_for_commit_transaction=There is no begin transaction for commit transaction
|
||||
|
||||
RollbackTransactionCheck_No_begin_transaction_for_rollback_transaction=There is no begin transaction for rollback transaction
|
||||
|
||||
RollbackTransactionCheck_No_commit_transaction_for_begin_transaction=There is no commit transaction for begin transaction
|
||||
|
||||
CommitTransactionCheck_No_rollback_transaction_for_begin_transaction=There is no rollback transaction for begin transaction
|
||||
|
||||
CommitTransactionCheck_Should_be_no_executable_code_between_commit_and_exception=There should be no executable code between commit transaction and exception
|
||||
|
||||
RollbackTransactionCheck_Should_be_no_executable_code_between_exception_and_rollback=There should be no executable code between exception and rollback transaction
|
||||
|
||||
CommitTransactionCheck_Transaction_contains_empty_except=The transaction contains an empty exception block
|
||||
|
||||
CommitTransactionCheck_Transactions_is_broken=Commit transaction is incorrect
|
||||
|
||||
CommitTransactionCheck_Transactions_is_broken_des=Commit transaction must be in a try-catch, there should be no executable code between commit transaction and exception, there is no begin transaction for commit transaction, there is no rollback transaction for begin transaction.
|
||||
|
||||
CommonModuleNamedSelfReferenceCheck_description=Excessive named self reference
|
||||
|
||||
CommonModuleNamedSelfReferenceCheck_issue=Excessive named self reference
|
||||
@ -231,6 +251,12 @@ RegionEmptyCheck_description = Check that module region is empty
|
||||
|
||||
RegionEmptyCheck_title = Region is empty
|
||||
|
||||
RollbackTransactionCheck_Rollback_transaction_must_be_in_try_catch=Rollback transaction must be in a try-catch
|
||||
|
||||
RollbackTransactionCheck_Transactions_is_broken=Rollback transaction is incorrect
|
||||
|
||||
RollbackTransactionCheck_Transactions_is_broken_des=Rollback transaction must be in a try-catch, there should be no executable code between exception and rollback transaction, there is no begin transaction for rollback transaction, there is no commit transaction for begin transaction.
|
||||
|
||||
SelfReferenceCheck_check_only_existing_form_properties=Check only existing form properties
|
||||
|
||||
SelfReferenceCheck_Description=Excessive usage of self reference (when referencing method, property or attribute)
|
||||
|
@ -40,6 +40,30 @@ ChangeAndValidateInsteadOfAroundCheck_description = Проверяет, что
|
||||
|
||||
ChangeAndValidateInsteadOfAroundCheck_title = Используется аннотация &ИзменениеИКонтроль вместо &Вместо
|
||||
|
||||
CommitTransactionCheck_Commit_transaction_must_be_in_try_catch=Вызов "ЗафиксироватьТранзакцию()" находится вне конструкции "Попытка... Исключение"
|
||||
|
||||
CommitTransactionCheck_No_begin_transaction_for_commit_transaction=Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ЗафиксироватьТранзакцию()"
|
||||
|
||||
CommitTransactionCheck_No_begin_transaction_for_rollback_transaction=Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ОтменитьТранзакцию()"
|
||||
|
||||
CommitTransactionCheck_No_commit_transaction_for_begin_transaction=Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ЗафиксироватьТранзакцию()"
|
||||
|
||||
CommitTransactionCheck_No_rollback_transaction_for_begin_transaction=Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ОтменитьТранзакцию()"
|
||||
|
||||
CommitTransactionCheck_Should_be_no_executable_code_between_commit_and_exception=Mежду "ЗафиксироватьТранзакцию()" и "Исключение" есть исполняемый код, который может вызвать исключение
|
||||
|
||||
CommitTransactionCheck_Should_be_no_executable_code_between_exception_and_rollback=Mежду "Исключение" и "ОтменитьТранзакцию()" есть исполняемый код, который может вызвать исключение
|
||||
|
||||
CommitTransactionCheck_Transaction_contains_empty_except=Транзакция содержит пустой блок Исключение
|
||||
|
||||
CommitTransactionCheck_Transactions_is_broken=Нарушена схема работы с "ЗафиксироватьТранзакцию()"
|
||||
|
||||
CommitTransactionCheck_Transactions_is_broken_des=Вызов "ЗафиксироватьТранзакцию()" находится вне конструкции "Попытка... Исключение". Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ЗафиксироватьТранзакцию()". Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ОтменитьТранзакцию()". Mежду "ЗафиксироватьТранзакцию()" и "Исключение" есть исполняемый код, который может вызвать исключение.
|
||||
|
||||
RollbackTransactionCheck_Transactions_is_broken=Нарушена схема работы с "ОтменитьТранзакцию()"
|
||||
|
||||
RollbackTransactionCheck_Transactions_is_broken_des=Вызов "ОтменитьТранзакцию()" находится вне конструкции "Попытка... Исключение". Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ОтменитьТранзакцию()". Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ЗафиксироватьТранзакцию()". Mежду "Исключение" и "ОтменитьТранзакцию()" есть исполняемый код, который может вызвать исключение.
|
||||
|
||||
CommonModuleNamedSelfReferenceCheck_description=Избыточное обращение по собственному имени
|
||||
|
||||
CommonModuleNamedSelfReferenceCheck_issue=Избыточное обращение по собственному имени
|
||||
@ -234,6 +258,8 @@ RegionEmptyCheck_description = Проверяет что область моду
|
||||
|
||||
RegionEmptyCheck_title = Область пустая
|
||||
|
||||
RollbackTransactionCheck_Rollback_transaction_must_be_in_try_catch=Вызов "ОтменитьТранзакцию()" находится вне конструкции "Попытка... Исключение"
|
||||
|
||||
SelfReferenceCheck_check_only_existing_form_properties=Проверять только существовующие свойства в форме
|
||||
|
||||
SelfReferenceCheck_Description=Избыточное обращение внутри модуля через псевдоним "ЭтотОбъект" (к методу, свойству или реквизиту)
|
||||
|
@ -0,0 +1,16 @@
|
||||
Процедура Тест()
|
||||
|
||||
НачатьТранзакцию();
|
||||
ЗафиксироватьТранзакцию();
|
||||
Попытка
|
||||
// 2. Вся логика блокировки и обработки данных размещается в блоке Попытка-Исключение
|
||||
// 3. В самом конце обработки данных выполняется попытка зафиксировать транзакцию
|
||||
Исключение
|
||||
// 4. В случае любых проблем с СУБД, транзакция сначала отменяется...
|
||||
ОтменитьТранзакцию();
|
||||
// 5. ...затем проблема фиксируется в журнале регистрации...
|
||||
// 6. ... после чего, проблема передается дальше вызывающему коду.
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
|
||||
КонецПроцедуры
|
@ -0,0 +1,15 @@
|
||||
Процедура Тест()
|
||||
|
||||
Попытка
|
||||
// 2. Вся логика блокировки и обработки данных размещается в блоке Попытка-Исключение
|
||||
// 3. В самом конце обработки данных выполняется попытка зафиксировать транзакцию
|
||||
ЗафиксироватьТранзакцию();
|
||||
Исключение
|
||||
// 4. В случае любых проблем с СУБД, транзакция сначала отменяется...
|
||||
ОтменитьТранзакцию();
|
||||
// 5. ...затем проблема фиксируется в журнале регистрации...
|
||||
// 6. ... после чего, проблема передается дальше вызывающему коду.
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
|
||||
КонецПроцедуры
|
@ -0,0 +1,14 @@
|
||||
Процедура Тест()
|
||||
|
||||
Попытка
|
||||
// 2. Вся логика блокировки и обработки данных размещается в блоке Попытка-Исключение
|
||||
// 3. В самом конце обработки данных выполняется попытка зафиксировать транзакцию
|
||||
Исключение
|
||||
// 4. В случае любых проблем с СУБД, транзакция сначала отменяется...
|
||||
ОтменитьТранзакцию();
|
||||
// 5. ...затем проблема фиксируется в журнале регистрации...
|
||||
// 6. ... после чего, проблема передается дальше вызывающему коду.
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
|
||||
КонецПроцедуры
|
@ -0,0 +1,16 @@
|
||||
Процедура Тест()
|
||||
|
||||
НачатьТранзакцию();
|
||||
Попытка
|
||||
// 2. Вся логика блокировки и обработки данных размещается в блоке Попытка-Исключение
|
||||
// 3. В самом конце обработки данных выполняется попытка зафиксировать транзакцию
|
||||
А = 2 + 2;
|
||||
Исключение
|
||||
// 4. В случае любых проблем с СУБД, транзакция сначала отменяется...
|
||||
ОтменитьТранзакцию();
|
||||
// 5. ...затем проблема фиксируется в журнале регистрации...
|
||||
// 6. ... после чего, проблема передается дальше вызывающему коду.
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
|
||||
КонецПроцедуры
|
@ -0,0 +1,15 @@
|
||||
Процедура Тест()
|
||||
|
||||
НачатьТранзакцию();
|
||||
Попытка
|
||||
// 2. Вся логика блокировки и обработки данных размещается в блоке Попытка-Исключение
|
||||
// 3. В самом конце обработки данных выполняется попытка зафиксировать транзакцию
|
||||
ЗафиксироватьТранзакцию();
|
||||
Исключение
|
||||
// 4. В случае любых проблем с СУБД, транзакция сначала отменяется...
|
||||
// 5. ...затем проблема фиксируется в журнале регистрации...
|
||||
// 6. ... после чего, проблема передается дальше вызывающему коду.
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
|
||||
КонецПроцедуры
|
@ -0,0 +1,18 @@
|
||||
Процедура Тест()
|
||||
|
||||
НачатьТранзакцию();
|
||||
Попытка
|
||||
// 2. Вся логика блокировки и обработки данных размещается в блоке Попытка-Исключение
|
||||
// 3. В самом конце обработки данных выполняется попытка зафиксировать транзакцию
|
||||
ЗафиксироватьТранзакцию();
|
||||
Исключение
|
||||
// 4. В случае любых проблем с СУБД, транзакция сначала отменяется...
|
||||
|
||||
// 5. ...затем проблема фиксируется в журнале регистрации...
|
||||
// 6. ... после чего, проблема передается дальше вызывающему коду.
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
|
||||
ОтменитьТранзакцию();
|
||||
|
||||
КонецПроцедуры
|
@ -0,0 +1,17 @@
|
||||
Процедура Тест()
|
||||
|
||||
НачатьТранзакцию();
|
||||
Попытка
|
||||
// 2. Вся логика блокировки и обработки данных размещается в блоке Попытка-Исключение
|
||||
// 3. В самом конце обработки данных выполняется попытка зафиксировать транзакцию
|
||||
ЗафиксироватьТранзакцию();
|
||||
Тест();
|
||||
Исключение
|
||||
// 4. В случае любых проблем с СУБД, транзакция сначала отменяется...
|
||||
ОтменитьТранзакцию();
|
||||
// 5. ...затем проблема фиксируется в журнале регистрации...
|
||||
// 6. ... после чего, проблема передается дальше вызывающему коду.
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
|
||||
КонецПроцедуры
|
@ -0,0 +1,17 @@
|
||||
Процедура Тест()
|
||||
|
||||
НачатьТранзакцию();
|
||||
Попытка
|
||||
// 2. Вся логика блокировки и обработки данных размещается в блоке Попытка-Исключение
|
||||
// 3. В самом конце обработки данных выполняется попытка зафиксировать транзакцию
|
||||
ЗафиксироватьТранзакцию();
|
||||
Исключение
|
||||
Тест();
|
||||
// 4. В случае любых проблем с СУБД, транзакция сначала отменяется...
|
||||
ОтменитьТранзакцию();
|
||||
// 5. ...затем проблема фиксируется в журнале регистрации...
|
||||
// 6. ... после чего, проблема передается дальше вызывающему коду.
|
||||
ВызватьИсключение;
|
||||
КонецПопытки;
|
||||
|
||||
КонецПроцедуры
|
@ -0,0 +1,85 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2022, 1C-Soft LLC and others.
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* 1C-Soft LLC - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.e1c.v8codestyle.bsl.check.itests;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com._1c.g5.v8.dt.validation.marker.Marker;
|
||||
import com.e1c.v8codestyle.bsl.check.CommitTransactionCheck;
|
||||
|
||||
/**
|
||||
* Tests for {@link CommitTransactionCheck} check.
|
||||
*
|
||||
* @author Artem Iliukhin
|
||||
*/
|
||||
public class CommitTransactionCheckTest
|
||||
extends AbstractSingleModuleTestBase
|
||||
{
|
||||
|
||||
/**
|
||||
* Instantiates a new commit transaction check test.
|
||||
*/
|
||||
public CommitTransactionCheckTest()
|
||||
{
|
||||
super(CommitTransactionCheck.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommitTransactionMustBeInTtryCatch() throws Exception
|
||||
{
|
||||
updateModule(FOLDER_RESOURCE + "commit-transaction-must-be-in-try-catch.bsl");
|
||||
|
||||
List<Marker> markers = getModuleMarkers();
|
||||
assertEquals(1, markers.size());
|
||||
Marker marker = markers.get(0);
|
||||
assertEquals("Commit transaction must be in a try-catch", marker.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoBeginTransactionForCommitTransaction() throws Exception
|
||||
{
|
||||
updateModule(FOLDER_RESOURCE + "no-begin-transaction-for-commit-transaction.bsl");
|
||||
|
||||
List<Marker> markers = getModuleMarkers();
|
||||
assertEquals(1, markers.size());
|
||||
Marker marker = markers.get(0);
|
||||
assertEquals("There is no begin transaction for commit transaction", marker.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoRollbackTransactionForBeginTransaction() throws Exception
|
||||
{
|
||||
updateModule(FOLDER_RESOURCE + "no-rollback-transaction-for-begin-transaction.bsl");
|
||||
|
||||
List<Marker> markers = getModuleMarkers();
|
||||
assertEquals(1, markers.size());
|
||||
Marker marker = markers.get(0);
|
||||
assertEquals("There is no rollback transaction for begin transaction", marker.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldBeNoExecutableCodebetweenCommitAndException() throws Exception
|
||||
{
|
||||
updateModule(FOLDER_RESOURCE + "should-be-no-executable-code-between-commit-and-exception.bsl");
|
||||
|
||||
List<Marker> markers = getModuleMarkers();
|
||||
assertEquals(1, markers.size());
|
||||
Marker marker = markers.get(0);
|
||||
assertEquals("There should be no executable code between commit transaction and exception",
|
||||
marker.getMessage());
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2022, 1C-Soft LLC and others.
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* 1C-Soft LLC - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.e1c.v8codestyle.bsl.check.itests;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com._1c.g5.v8.dt.validation.marker.Marker;
|
||||
import com.e1c.v8codestyle.bsl.check.RollbackTransactionCheck;
|
||||
|
||||
/**
|
||||
* Tests for {@link RollbackTransactionCheck} check.
|
||||
*
|
||||
* @author Artem Iliukhin
|
||||
*/
|
||||
public class RollbackTransactionCheckTest
|
||||
extends AbstractSingleModuleTestBase
|
||||
{
|
||||
|
||||
/**
|
||||
* Instantiates a new commit transaction check test.
|
||||
*/
|
||||
public RollbackTransactionCheckTest()
|
||||
{
|
||||
super(RollbackTransactionCheck.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRollbackTransactionMustBeInTtryCatch() throws Exception
|
||||
{
|
||||
updateModule(FOLDER_RESOURCE + "rollback-transaction-must-be-in-try-catch.bsl");
|
||||
|
||||
List<Marker> markers = getModuleMarkers();
|
||||
assertEquals(1, markers.size());
|
||||
Marker marker = markers.get(0);
|
||||
assertEquals("Rollback transaction must be in a try-catch", marker.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoBeginTransactionForRollbackTransaction() throws Exception
|
||||
{
|
||||
updateModule(FOLDER_RESOURCE + "no-begin-transaction-for-rollback-transaction.bsl");
|
||||
|
||||
List<Marker> markers = getModuleMarkers();
|
||||
assertEquals(1, markers.size());
|
||||
Marker marker = markers.get(0);
|
||||
assertEquals("There is no begin transaction for rollback transaction", marker.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoCommitTransactionForBeginTransaction() throws Exception
|
||||
{
|
||||
updateModule(FOLDER_RESOURCE + "no-commit-transaction-for-begin-transaction.bsl");
|
||||
|
||||
List<Marker> markers = getModuleMarkers();
|
||||
assertEquals(1, markers.size());
|
||||
Marker marker = markers.get(0);
|
||||
assertEquals("There is no commit transaction for begin transaction", marker.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldBeNoExecutableCodebetweenExceptionAndRollback() throws Exception
|
||||
{
|
||||
updateModule(FOLDER_RESOURCE + "should-be-no-executable-code-between-exception-and-rollback.bsl");
|
||||
|
||||
List<Marker> markers = getModuleMarkers();
|
||||
assertEquals(1, markers.size());
|
||||
Marker marker = markers.get(0);
|
||||
assertEquals("There should be no executable code between exception and rollback transaction",
|
||||
marker.getMessage());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user