You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2018/08/30 12:24:12 UTC

[06/45] ignite git commit: IGNITE-4191: MVCC and transactional SQL support. Joint multi-man-years efforts of Semen Boikov, Igor Seliverstov, Alexander Paschenko, Igor Sapego, Sergey Kalashnikov, Roman Kondakov, Pavel Kuznetsov, Ivan Pavlukhin, Andrey Mas

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc-test/src/sql_get_info_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/sql_get_info_test.cpp b/modules/platforms/cpp/odbc-test/src/sql_get_info_test.cpp
index 630597c..7842704 100644
--- a/modules/platforms/cpp/odbc-test/src/sql_get_info_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/sql_get_info_test.cpp
@@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(TestValues)
     CheckStrInfo(SQL_LIKE_ESCAPE_CLAUSE, "N");
     CheckStrInfo(SQL_MAX_ROW_SIZE_INCLUDES_LONG, "Y");
     CheckStrInfo(SQL_MULT_RESULT_SETS, "N");
-    CheckStrInfo(SQL_MULTIPLE_ACTIVE_TXN, "N");
+    CheckStrInfo(SQL_MULTIPLE_ACTIVE_TXN, "Y");
     CheckStrInfo(SQL_ORDER_BY_COLUMNS_IN_SELECT, "N");
     CheckStrInfo(SQL_PROCEDURE_TERM, "stored procedure");
     CheckStrInfo(SQL_PROCEDURES, "N");
@@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(TestValues)
     CheckIntInfo(SQL_CREATE_VIEW, 0);
     CheckIntInfo(SQL_CURSOR_SENSITIVITY, SQL_INSENSITIVE);
     CheckIntInfo(SQL_DDL_INDEX, SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX);
-    CheckIntInfo(SQL_DEFAULT_TXN_ISOLATION, 0);
+    CheckIntInfo(SQL_DEFAULT_TXN_ISOLATION, SQL_TXN_REPEATABLE_READ);
     CheckIntInfo(SQL_DROP_ASSERTION, 0);
     CheckIntInfo(SQL_DROP_CHARACTER_SET, 0);
     CheckIntInfo(SQL_DROP_COLLATION, 0);
@@ -212,7 +212,7 @@ BOOST_AUTO_TEST_CASE(TestValues)
     CheckIntInfo(SQL_SQL92_GRANT, 0);
     CheckIntInfo(SQL_SQL92_REVOKE, 0);
     CheckIntInfo(SQL_STANDARD_CLI_CONFORMANCE, 0);
-    CheckIntInfo(SQL_TXN_ISOLATION_OPTION, 0);
+    CheckIntInfo(SQL_TXN_ISOLATION_OPTION, SQL_TXN_REPEATABLE_READ);
     CheckIntInfo(SQL_UNION, SQL_U_UNION | SQL_U_UNION_ALL);
 
     CheckIntInfo(SQL_SCHEMA_USAGE, SQL_SU_DML_STATEMENTS | SQL_SU_TABLE_DEFINITION | SQL_SU_PRIVILEGE_DEFINITION |
@@ -384,7 +384,7 @@ BOOST_AUTO_TEST_CASE(TestValues)
     CheckShortInfo(SQL_MAX_CONCURRENT_ACTIVITIES, 0);
     CheckShortInfo(SQL_CURSOR_COMMIT_BEHAVIOR, SQL_CB_PRESERVE);
     CheckShortInfo(SQL_CURSOR_ROLLBACK_BEHAVIOR, SQL_CB_PRESERVE);
-    CheckShortInfo(SQL_TXN_CAPABLE, SQL_TC_NONE);
+    CheckShortInfo(SQL_TXN_CAPABLE, SQL_TC_DDL_COMMIT);
     CheckShortInfo(SQL_QUOTED_IDENTIFIER_CASE, SQL_IC_SENSITIVE);
     CheckShortInfo(SQL_ACTIVE_ENVIRONMENTS, 0);
     CheckShortInfo(SQL_CONCAT_NULL_BEHAVIOR, SQL_CB_NULL);

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc-test/src/transaction_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/transaction_test.cpp b/modules/platforms/cpp/odbc-test/src/transaction_test.cpp
new file mode 100644
index 0000000..fb2b6c9
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/src/transaction_test.cpp
@@ -0,0 +1,738 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef _WIN32
+#   include <windows.h>
+#endif
+
+#include <sql.h>
+#include <sqlext.h>
+
+#include <string>
+
+#ifndef _MSC_VER
+#   define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include "ignite/ignition.h"
+
+#include "test_utils.h"
+#include "odbc_test_suite.h"
+
+using namespace ignite;
+using namespace ignite_test;
+
+using namespace boost::unit_test;
+
+/**
+ * Test setup fixture.
+ */
+struct TransactionTestSuiteFixture : public odbc::OdbcTestSuite
+{
+    static Ignite StartAdditionalNode(const char* name)
+    {
+        return StartTestNode("queries-transaction.xml", name);
+    }
+
+    /**
+     * Constructor.
+     */
+    TransactionTestSuiteFixture() :
+        grid(StartAdditionalNode("NodeMain"))
+    {
+        // No-op.
+    }
+
+    /**
+     * Destructor.
+     */
+    ~TransactionTestSuiteFixture()
+    {
+        // No-op.
+    }
+
+    /**
+     * Insert test string value in cache and make all the neccessary checks.
+     *
+     * @param key Key.
+     * @param value Value.
+     */
+    void InsertTestValue(int64_t key, const std::string& value)
+    {
+        SQLCHAR insertReq[] = "INSERT INTO TestType(_key, strField) VALUES(?, ?)";
+
+        SQLRETURN ret;
+
+        ret = SQLPrepare(stmt, insertReq, SQL_NTS);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        char strField[1024] = { 0 };
+        SQLLEN strFieldLen = 0;
+
+        ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &key, 0, 0);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(strField),
+            sizeof(strField), &strField, sizeof(strField), &strFieldLen);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        strncpy(strField, value.c_str(), sizeof(strField));
+        strFieldLen = SQL_NTS;
+
+        ret = SQLExecute(stmt);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        SQLLEN affected = 0;
+        ret = SQLRowCount(stmt, &affected);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        BOOST_CHECK_EQUAL(affected, 1);
+
+        ret = SQLMoreResults(stmt);
+
+        if (ret != SQL_NO_DATA)
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ResetStatement();
+    }
+
+    /**
+     * Update test string value in cache and make all the neccessary checks.
+     *
+     * @param key Key.
+     * @param value Value.
+     */
+    void UpdateTestValue(int64_t key, const std::string& value)
+    {
+        SQLCHAR insertReq[] = "UPDATE TestType SET strField=? WHERE _key=?";
+
+        SQLRETURN ret;
+
+        ret = SQLPrepare(stmt, insertReq, SQL_NTS);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        char strField[1024] = { 0 };
+        SQLLEN strFieldLen = 0;
+
+        ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(strField),
+            sizeof(strField), &strField, sizeof(strField), &strFieldLen);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &key, 0, 0);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        strncpy(strField, value.c_str(), sizeof(strField));
+        strFieldLen = SQL_NTS;
+
+        ret = SQLExecute(stmt);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        SQLLEN affected = 0;
+        ret = SQLRowCount(stmt, &affected);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        BOOST_CHECK_EQUAL(affected, 1);
+
+        ret = SQLMoreResults(stmt);
+
+        if (ret != SQL_NO_DATA)
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ResetStatement();
+    }
+
+    /**
+     * Delete test string value.
+     *
+     * @param key Key.
+     */
+    void DeleteTestValue(int64_t key)
+    {
+        SQLCHAR insertReq[] = "DELETE FROM TestType WHERE _key=?";
+
+        SQLRETURN ret;
+
+        ret = SQLPrepare(stmt, insertReq, SQL_NTS);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &key, 0, 0);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLExecute(stmt);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        SQLLEN affected = 0;
+        ret = SQLRowCount(stmt, &affected);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        BOOST_CHECK_EQUAL(affected, 1);
+
+        ret = SQLMoreResults(stmt);
+
+        if (ret != SQL_NO_DATA)
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ResetStatement();
+    }
+
+    /**
+     * Selects and checks the value.
+     *
+     * @param key Key.
+     * @param expect Expected value.
+     */
+    void CheckTestValue(int64_t key, const std::string& expect)
+    {
+        // Just selecting everything to make sure everything is OK
+        SQLCHAR selectReq[] = "SELECT strField FROM TestType WHERE _key = ?";
+
+        char strField[1024] = { 0 };
+        SQLLEN strFieldLen = 0;
+
+        SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_CHAR, &strField, sizeof(strField), &strFieldLen);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &key, 0, 0);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLExecDirect(stmt, selectReq, sizeof(selectReq));
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLFetch(stmt);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        BOOST_CHECK_EQUAL(std::string(strField, strFieldLen), expect);
+
+        ret = SQLFetch(stmt);
+
+        BOOST_CHECK_EQUAL(ret, SQL_NO_DATA);
+
+        ret = SQLMoreResults(stmt);
+
+        if (ret != SQL_NO_DATA)
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ResetStatement();
+    }
+
+    /**
+     * Selects and checks that value is absent.
+     *
+     * @param key Key.
+     */
+    void CheckNoTestValue(int64_t key)
+    {
+        // Just selecting everything to make sure everything is OK
+        SQLCHAR selectReq[] = "SELECT strField FROM TestType WHERE _key = ?";
+
+        char strField[1024] = { 0 };
+        SQLLEN strFieldLen = 0;
+
+        SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_CHAR, &strField, sizeof(strField), &strFieldLen);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &key, 0, 0);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLExecDirect(stmt, selectReq, sizeof(selectReq));
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLFetch(stmt);
+
+        BOOST_CHECK_EQUAL(ret, SQL_NO_DATA);
+
+        ret = SQLMoreResults(stmt);
+
+        if (ret != SQL_NO_DATA)
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ResetStatement();
+    }
+
+    /**
+     * Reset statement state.
+     */
+    void ResetStatement()
+    {
+        SQLRETURN ret = SQLFreeStmt(stmt, SQL_RESET_PARAMS);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLFreeStmt(stmt, SQL_UNBIND);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+    }
+
+    /** Node started during the test. */
+    Ignite grid;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TransactionTestSuite, TransactionTestSuiteFixture)
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionCommit)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionRollbackInsert)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    CheckNoTestValue(42);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionRollbackUpdate1)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    UpdateTestValue(42, "Other");
+
+    CheckTestValue(42, "Other");
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionRollbackUpdate2)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    CheckTestValue(42, "Some");
+
+    UpdateTestValue(42, "Other");
+
+    CheckTestValue(42, "Other");
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionRollbackDelete1)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    DeleteTestValue(42);
+
+    CheckNoTestValue(42);
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionRollbackDelete2)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    CheckTestValue(42, "Some");
+
+    DeleteTestValue(42);
+
+    CheckNoTestValue(42);
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionTxModeError)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=error");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    ret = ExecQuery("BEGIN");
+
+    BOOST_CHECK_EQUAL(ret, SQL_ERROR);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionTxModeIgnore)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=ignore");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    ret = ExecQuery("BEGIN");
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    CheckNoTestValue(42);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionTxModeCommit)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=commit");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    ret = ExecQuery("BEGIN");
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    UpdateTestValue(42, "Other");
+
+    CheckTestValue(42, "Other");
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentCommit)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentRollbackInsert)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+    CheckNoTestValue(42);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentRollbackUpdate1)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    UpdateTestValue(42, "Other");
+
+    CheckTestValue(42, "Other");
+
+    ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentRollbackUpdate2)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+    CheckTestValue(42, "Some");
+
+    UpdateTestValue(42, "Other");
+
+    CheckTestValue(42, "Other");
+
+    ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentRollbackDelete1)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    DeleteTestValue(42);
+
+    CheckNoTestValue(42);
+
+    ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentRollbackDelete2)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    CheckTestValue(42, "Some");
+
+    ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+    CheckTestValue(42, "Some");
+
+    DeleteTestValue(42);
+
+    CheckNoTestValue(42);
+
+    ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentTxModeError)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=error");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    ret = ExecQuery("BEGIN");
+
+    BOOST_CHECK_EQUAL(ret, SQL_ERROR);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentTxModeIgnore)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=ignore");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    ret = ExecQuery("BEGIN");
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+    CheckNoTestValue(42);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentTxModeCommit)
+{
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=commit");
+
+    SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    InsertTestValue(42, "Some");
+
+    ret = ExecQuery("BEGIN");
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+    UpdateTestValue(42, "Other");
+
+    CheckTestValue(42, "Other");
+
+    ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+    CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/Makefile.am b/modules/platforms/cpp/odbc/Makefile.am
index 90e4dc9..f706f4f 100644
--- a/modules/platforms/cpp/odbc/Makefile.am
+++ b/modules/platforms/cpp/odbc/Makefile.am
@@ -83,6 +83,7 @@ libignite_odbc_la_SOURCES = \
     src/protocol_version.cpp \
     src/result_page.cpp \
     src/row.cpp \
+    src/nested_tx_mode.cpp \
     src/message.cpp \
     src/column.cpp \
     src/statement.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h b/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
index c19f29d..27de7e8 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
@@ -26,6 +26,7 @@
 #include "ignite/odbc/config/settable_value.h"
 #include "ignite/odbc/ssl/ssl_mode.h"
 #include "ignite/odbc/end_point.h"
+#include "ignite/odbc/nested_tx_mode.h"
 
 namespace ignite
 {
@@ -104,6 +105,9 @@ namespace ignite
 
                     /** Default value for password attribute. */
                     static const std::string password;
+
+                    /** Default value for nestedTxMode attribute. */
+                    static const NestedTxMode::Type nestedTxMode;
                 };
 
                 /**
@@ -537,6 +541,27 @@ namespace ignite
                 bool IsPasswordSet() const;
 
                 /**
+                 * Get nested transaction mode.
+                 *
+                 * @return Nested transaction mode.
+                 */
+                NestedTxMode::Type GetNestedTxMode() const;
+
+                /**
+                 * Set nested transaction mode.
+                 *
+                 * @param mode Nested transaction mode.
+                 */
+                void SetNestedTxMode(NestedTxMode::Type mode);
+
+                /**
+                 * Check if the value set.
+                 *
+                 * @return @true if the value set.
+                 */
+                bool IsNestedTxModeSet() const;
+
+                /**
                  * Get argument map.
                  *
                  * @param res Resulting argument map.
@@ -613,6 +638,9 @@ namespace ignite
 
                 /** Password. */
                 SettableValue<std::string> password;
+
+                /** Nested transaction mode. */
+                SettableValue<NestedTxMode::Type> nestedTxMode;
             };
 
             template<>
@@ -642,6 +670,10 @@ namespace ignite
             template<>
             void Configuration::AddToMap<ssl::SslMode::Type>(ArgumentMap& map, const std::string& key,
                 const SettableValue<ssl::SslMode::Type>& value);
+
+            template<>
+            void Configuration::AddToMap<NestedTxMode::Type>(ArgumentMap& map, const std::string& key,
+                const SettableValue<NestedTxMode::Type>& value);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/config/connection_string_parser.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/config/connection_string_parser.h b/modules/platforms/cpp/odbc/include/ignite/odbc/config/connection_string_parser.h
index 2bfe331..605109e 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/config/connection_string_parser.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/config/connection_string_parser.h
@@ -97,6 +97,9 @@ namespace ignite
 
                     /** Connection attribute keyword for password attribute. */
                     static const std::string password;
+
+                    /** Connection attribute keyword for nestedTxMode attribute. */
+                    static const std::string nestedTxMode;
                 };
 
                 /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h b/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
index 68d7816..b3ae5fc 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
@@ -33,6 +33,7 @@ namespace ignite
 {
     namespace odbc
     {
+        class Environment;
         class Statement;
 
         /**
@@ -99,6 +100,11 @@ namespace ignite
             void Release();
 
             /**
+             * Deregister self from the parent.
+             */
+            void Deregister();
+
+            /**
              * Create statement associated with the connection.
              *
              * @return Pointer to valid instance on success and NULL on failure.
@@ -141,6 +147,13 @@ namespace ignite
             const config::Configuration& GetConfiguration() const;
 
             /**
+             * Is auto commit.
+             *
+             * @return @c true if the auto commit is enabled.
+             */
+            bool IsAutoCommit();
+
+            /**
              * Create diagnostic record associated with the Connection instance.
              *
              * @param sqlState SQL state.
@@ -432,7 +445,10 @@ namespace ignite
             /**
              * Constructor.
              */
-            Connection();
+            Connection(Environment* env);
+
+            /** Parent. */
+            Environment* env;
 
             /** Client Socket. */
             std::auto_ptr<SocketClient> socket;
@@ -443,6 +459,9 @@ namespace ignite
             /** Login timeout in seconds. */
             int32_t loginTimeout;
 
+            /** Autocommit flag. */
+            bool autoCommit;
+
             /** Message parser. */
             Parser parser;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
index 46d79ce..613cbf4 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
@@ -82,6 +82,13 @@ namespace ignite
                  */
                 virtual void AddStatusRecord(const OdbcError& err) = 0;
 
+                /**
+                 * Add new status record.
+                 *
+                 * @param rec Record.
+                 */
+                virtual void AddStatusRecord(const DiagnosticRecord& rec) = 0;
+
             protected:
                 /**
                  * Default constructor.

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
index f1e9164..d8cfeb7 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
@@ -69,7 +69,7 @@ namespace ignite
                  *
                  * @return Diagnostic record.
                  */
-                virtual const diagnostic::DiagnosticRecordStorage& GetDiagnosticRecords() const
+                virtual const DiagnosticRecordStorage& GetDiagnosticRecords() const
                 {
                     return diagnosticRecords;
                 }
@@ -79,7 +79,7 @@ namespace ignite
                  *
                  * @return Diagnostic record.
                  */
-                virtual diagnostic::DiagnosticRecordStorage& GetDiagnosticRecords()
+                virtual DiagnosticRecordStorage& GetDiagnosticRecords()
                 {
                     return diagnosticRecords;
                 }
@@ -110,6 +110,13 @@ namespace ignite
                  */
                 virtual void AddStatusRecord(const OdbcError& err);
 
+                /**
+                 * Add new status record.
+                 *
+                 * @param rec Record.
+                 */
+                virtual void AddStatusRecord(const DiagnosticRecord& rec);
+
             protected:
                 /** Diagnostic records. */
                 DiagnosticRecordStorage diagnosticRecords;

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/environment.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/environment.h b/modules/platforms/cpp/odbc/include/ignite/odbc/environment.h
index 3eeade6..e6a171f 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/environment.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/environment.h
@@ -18,6 +18,8 @@
 #ifndef _IGNITE_ODBC_ENVIRONMENT
 #define _IGNITE_ODBC_ENVIRONMENT
 
+#include <set>
+
 #include "ignite/odbc/diagnostic/diagnosable_adapter.h"
 
 namespace ignite
@@ -32,6 +34,9 @@ namespace ignite
         class Environment : public diagnostic::DiagnosableAdapter
         {
         public:
+            /** Connection set type. */
+            typedef std::set<Connection*> ConnectionSet;
+
             /**
              * Constructor.
              */
@@ -50,6 +55,13 @@ namespace ignite
             Connection* CreateConnection();
 
             /**
+             * Deregister connection.
+             *
+             * @param conn Connection to deregister.
+             */
+            void DeregisterConnection(Connection* conn);
+
+            /**
              * Perform transaction commit on all the associated connections.
              */
             void TransactionCommit();
@@ -125,6 +137,9 @@ namespace ignite
              */
             SqlResult::Type InternalGetAttribute(int32_t attr, app::ApplicationDataBuffer& buffer);
 
+            /** Assotiated connections. */
+            ConnectionSet connections;
+
             /** ODBC version. */
             int32_t odbcVersion;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
index e119d1f..87ba064 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
@@ -109,9 +109,10 @@ namespace ignite
              * @param sql SQL query.
              * @param params Query arguments.
              * @param timeout Timeout.
+             * @param autoCommit Auto commit flag.
              */
             QueryExecuteRequest(const std::string& schema, const std::string& sql, const app::ParameterSet& params,
-                int32_t timeout);
+                int32_t timeout, bool autoCommit);
 
             /**
              * Destructor.
@@ -137,6 +138,9 @@ namespace ignite
 
             /** Timeout. */
             int32_t timeout;
+
+            /** Auto commit. */
+            bool autoCommit;
         };
 
         /**
@@ -154,9 +158,11 @@ namespace ignite
              * @param begin Beginng of the interval.
              * @param end End of the interval.
              * @param timeout Timeout.
+             * @param autoCommit Auto commit flag.
              */
             QueryExecuteBatchtRequest(const std::string& schema, const std::string& sql,
-                const app::ParameterSet& params, SqlUlen begin, SqlUlen end, bool last, int32_t timeout);
+                const app::ParameterSet& params, SqlUlen begin, SqlUlen end, bool last, int32_t timeout,
+                bool autoCommit);
 
             /**
              * Destructor.
@@ -191,6 +197,9 @@ namespace ignite
 
             /** Timeout. */
             int32_t timeout;
+
+            /** Auto commit. */
+            bool autoCommit;
         };
 
         /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/nested_tx_mode.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/nested_tx_mode.h b/modules/platforms/cpp/odbc/include/ignite/odbc/nested_tx_mode.h
new file mode 100644
index 0000000..eb2598d
--- /dev/null
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/nested_tx_mode.h
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _IGNITE_ODBC_NESTED_TX_MODE
+#define _IGNITE_ODBC_NESTED_TX_MODE
+
+#include <set>
+#include <string>
+
+namespace ignite
+{
+    namespace odbc
+    {
+        /**
+         * Nested transaction mode.
+         */
+        struct NestedTxMode
+        {
+            /**
+             * Values.
+             */
+            enum Type
+            {
+                /** Commit current transaction if a new one started. */
+                AI_COMMIT = 1,
+
+                /** Ignore start of a new transaction. */
+                AI_IGNORE = 2,
+
+                /** Throw an error. */
+                AI_ERROR = 3,
+
+                /** Returned when value is unknown. */
+                AI_UNKNOWN = 100
+            };
+
+            /** Mode set type. */
+            typedef std::set<Type> ModeSet;
+
+            /**
+             * Get value from a string value.
+             *
+             * @param str String.
+             * @param dflt Value to return on error.
+             * @return Corresponding value on success and @c dflt on failure.
+             */
+            static Type FromString(const std::string& str, Type dflt = AI_UNKNOWN);
+
+            /**
+             * Convert value to a string.
+             *
+             * @param value Value.
+             * @return String value.
+             */
+            static std::string ToString(Type value);
+
+            /**
+             * Get set of all valid values.
+             *
+             * @return Set of all valid values.
+             */
+            static const ModeSet& GetValidValues();
+        };
+    }
+}
+
+#endif //_IGNITE_ODBC_NESTED_TX_MODE
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h b/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
index 0b64536..1a722e3 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
@@ -43,7 +43,7 @@ namespace ignite
             /** Version 2.3.2: added multiple statements support. */
             static const ProtocolVersion VERSION_2_3_2;
 
-            /** Version 2.5.0: added multiple statements support. */
+            /** Version 2.5.0: added authentication and transactions support. */
             static const ProtocolVersion VERSION_2_5_0;
 
             /** Version 2.7.0: added fields precision and scale. */

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
index 1666863..77974ad 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
@@ -61,6 +61,8 @@ namespace ignite
                             SKIP_REDUCER_ON_UPDATE_CHECK_BOX,
                             PROTOCOL_VERSION_LABEL,
                             PROTOCOL_VERSION_COMBO_BOX,
+                            NESTED_TX_MODE_LABEL,
+                            NESTED_TX_MODE_COMBO_BOX,
                             SSL_MODE_LABEL,
                             SSL_MODE_COMBO_BOX,
                             SSL_KEY_FILE_LABEL,
@@ -312,6 +314,12 @@ namespace ignite
                     /** Password edit. */
                     std::auto_ptr<Window> passwordEdit;
 
+                    /** Nested transaction mode label. */
+                    std::auto_ptr<Window> nestedTxModeLabel;
+
+                    /** Nested transaction mode combo box. */
+                    std::auto_ptr<Window> nestedTxModeComboBox;
+
                     /** Configuration. */
                     config::Configuration& config;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
index a94b479..e3bbb4e 100644
--- a/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
+++ b/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
@@ -36,7 +36,7 @@ namespace ignite
                 DsnConfigurationWindow::DsnConfigurationWindow(Window* parent, config::Configuration& config):
                     CustomWindow(parent, "IgniteConfigureDsn", "Configure Apache Ignite DSN"),
                     width(360),
-                    height(580),
+                    height(600),
                     connectionSettingsGroupBox(),
                     sslSettingsGroupBox(),
                     authSettingsGroupBox(),
@@ -59,6 +59,7 @@ namespace ignite
                     userEdit(),
                     passwordLabel(),
                     passwordEdit(),
+                    nestedTxModeComboBox(),
                     okButton(),
                     cancelButton(),
                     config(config),
@@ -286,7 +287,7 @@ namespace ignite
 
                 int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX)
                 {
-                    enum { LABEL_WIDTH = 80 };
+                    enum { LABEL_WIDTH = 130 };
 
                     int labelPosX = posX + INTERVAL;
 
@@ -309,6 +310,29 @@ namespace ignite
 
                     rowPos += INTERVAL + ROW_HEIGHT;
 
+                    nestedTxModeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT,
+                        "Nested Transaction Mode:", ChildId::NESTED_TX_MODE_LABEL);
+                    nestedTxModeComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT,
+                        "", ChildId::NESTED_TX_MODE_COMBO_BOX);
+
+                    int id = 0;
+
+                    const NestedTxMode::ModeSet& supported = NestedTxMode::GetValidValues();
+
+                    for (NestedTxMode::ModeSet::const_iterator it = supported.begin(); it != supported.end(); ++it)
+                    {
+                        nestedTxModeComboBox->AddString(NestedTxMode::ToString(*it));
+
+                        if (*it == config.GetNestedTxMode())
+                            nestedTxModeComboBox->SetSelection(id);
+
+                        ++id;
+                    }
+
+                    nestedTxModeComboBox->SetEnabled(version >= ProtocolVersion::VERSION_2_5_0);
+
+                    rowPos += INTERVAL + ROW_HEIGHT;
+
                     distributedJoinsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT,
                         "Distributed Joins", ChildId::DISTRIBUTED_JOINS_CHECK_BOX, config.IsDistributedJoins());
 
@@ -429,6 +453,7 @@ namespace ignite
                                     ProtocolVersion version = ProtocolVersion::FromString(versionStr);
                                     lazyCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_1_5);
                                     skipReducerOnUpdateCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_3_0);
+                                    nestedTxModeComboBox->SetEnabled(version >= ProtocolVersion::VERSION_2_5_0);
 
                                     break;
                                 }
@@ -568,13 +593,6 @@ namespace ignite
                 {
                     std::string pageSizeStr;
 
-                    bool distributedJoins;
-                    bool enforceJoinOrder;
-                    bool replicatedOnly;
-                    bool collocated;
-                    bool lazy;
-                    bool skipReducerOnUpdate;
-
                     pageSizeEdit->GetText(pageSizeStr);
 
                     int32_t pageSize = common::LexicalCast<int32_t>(pageSizeStr);
@@ -582,15 +600,22 @@ namespace ignite
                     if (pageSize <= 0)
                         pageSize = config.GetPageSize();
 
-                    distributedJoins = distributedJoinsCheckBox->IsChecked();
-                    enforceJoinOrder = enforceJoinOrderCheckBox->IsChecked();
-                    replicatedOnly = replicatedOnlyCheckBox->IsChecked();
-                    collocated = collocatedCheckBox->IsChecked();
-                    lazy = lazyCheckBox->IsChecked();
-                    skipReducerOnUpdate = skipReducerOnUpdateCheckBox->IsChecked();
+                    std::string nestedTxModeStr;
+
+                    nestedTxModeComboBox->GetText(nestedTxModeStr);
+
+                    NestedTxMode::Type mode = NestedTxMode::FromString(nestedTxModeStr, config.GetNestedTxMode());
+
+                    bool distributedJoins = distributedJoinsCheckBox->IsChecked();
+                    bool enforceJoinOrder = enforceJoinOrderCheckBox->IsChecked();
+                    bool replicatedOnly = replicatedOnlyCheckBox->IsChecked();
+                    bool collocated = collocatedCheckBox->IsChecked();
+                    bool lazy = lazyCheckBox->IsChecked();
+                    bool skipReducerOnUpdate = skipReducerOnUpdateCheckBox->IsChecked();
 
                     LOG_MSG("Retrieving arguments:");
                     LOG_MSG("Page size:              " << pageSize);
+                    LOG_MSG("Nested TX Mode:         " << NestedTxMode::ToString(mode));
                     LOG_MSG("Distributed Joins:      " << (distributedJoins ? "true" : "false"));
                     LOG_MSG("Enforce Join Order:     " << (enforceJoinOrder ? "true" : "false"));
                     LOG_MSG("Replicated only:        " << (replicatedOnly ? "true" : "false"));
@@ -599,6 +624,7 @@ namespace ignite
                     LOG_MSG("Skip reducer on update: " << (skipReducerOnUpdate ? "true" : "false"));
 
                     cfg.SetPageSize(pageSize);
+                    cfg.SetNestedTxMode(mode);
                     cfg.SetDistributedJoins(distributedJoins);
                     cfg.SetEnforceJoinOrder(enforceJoinOrder);
                     cfg.SetReplicatedOnly(replicatedOnly);

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
index 352913e..630dc27 100644
--- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
+++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
@@ -182,6 +182,7 @@
     <ClCompile Include="..\..\src\message.cpp" />
     <ClCompile Include="..\..\src\meta\column_meta.cpp" />
     <ClCompile Include="..\..\src\meta\table_meta.cpp" />
+    <ClCompile Include="..\..\src\nested_tx_mode.cpp" />
     <ClCompile Include="..\..\src\odbc.cpp" />
     <ClCompile Include="..\..\src\protocol_version.cpp" />
     <ClCompile Include="..\..\src\query\batch_query.cpp" />
@@ -230,6 +231,7 @@
     <ClInclude Include="..\..\include\ignite\odbc\meta\column_meta.h" />
     <ClInclude Include="..\..\include\ignite\odbc\meta\primary_key_meta.h" />
     <ClInclude Include="..\..\include\ignite\odbc\meta\table_meta.h" />
+    <ClInclude Include="..\..\include\ignite\odbc\nested_tx_mode.h" />
     <ClInclude Include="..\..\include\ignite\odbc\odbc_error.h" />
     <ClInclude Include="..\..\include\ignite\odbc\parser.h" />
     <ClInclude Include="..\..\include\ignite\odbc\protocol_version.h" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
index b1956aa..6da0111 100644
--- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
+++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
@@ -166,6 +166,9 @@
     <ClCompile Include="..\..\src\config\config_tools.cpp">
       <Filter>Code\config</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\nested_tx_mode.cpp">
+      <Filter>Code</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="module.def">
@@ -329,5 +332,8 @@
     <ClInclude Include="..\..\include\ignite\odbc\end_point.h">
       <Filter>Code</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\include\ignite\odbc\nested_tx_mode.h">
+      <Filter>Code</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/config/configuration.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/configuration.cpp b/modules/platforms/cpp/odbc/src/config/configuration.cpp
index ef102d2..a99894d 100644
--- a/modules/platforms/cpp/odbc/src/config/configuration.cpp
+++ b/modules/platforms/cpp/odbc/src/config/configuration.cpp
@@ -56,6 +56,8 @@ namespace ignite
             const std::string Configuration::DefaultValue::user = "";
             const std::string Configuration::DefaultValue::password = "";
 
+            const NestedTxMode::Type Configuration::DefaultValue::nestedTxMode = NestedTxMode::AI_ERROR;
+
             Configuration::Configuration() :
                 dsn(DefaultValue::dsn),
                 driver(DefaultValue::driver),
@@ -76,7 +78,8 @@ namespace ignite
                 sslCertFile(DefaultValue::sslCertFile),
                 sslCaFile(DefaultValue::sslCaFile),
                 user(DefaultValue::user),
-                password(DefaultValue::password)
+                password(DefaultValue::password),
+                nestedTxMode(DefaultValue::nestedTxMode)
             {
                 // No-op.
             }
@@ -404,6 +407,21 @@ namespace ignite
                 return password.IsSet();
             }
 
+            NestedTxMode::Type Configuration::GetNestedTxMode() const
+            {
+                return nestedTxMode.GetValue();
+            }
+
+            void Configuration::SetNestedTxMode(NestedTxMode::Type mode)
+            {
+                this->nestedTxMode.SetValue(mode);
+            }
+
+            bool Configuration::IsNestedTxModeSet() const
+            {
+                return nestedTxMode.IsSet();
+            }
+
             int32_t Configuration::GetPageSize() const
             {
                 return pageSize.GetValue();
@@ -431,6 +449,7 @@ namespace ignite
                 AddToMap(res, ConnectionStringParser::Key::sslCaFile, sslCaFile);
                 AddToMap(res, ConnectionStringParser::Key::user, user);
                 AddToMap(res, ConnectionStringParser::Key::password, password);
+                AddToMap(res, ConnectionStringParser::Key::nestedTxMode, nestedTxMode);
             }
 
             template<>
@@ -486,6 +505,14 @@ namespace ignite
                 if (value.IsSet())
                     map[key] = ssl::SslMode::ToString(value.GetValue());
             }
+
+            template<>
+            void Configuration::AddToMap(ArgumentMap& map, const std::string& key,
+                const SettableValue<NestedTxMode::Type>& value)
+            {
+                if (value.IsSet())
+                    map[key] = NestedTxMode::ToString(value.GetValue());
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/config/connection_info.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/connection_info.cpp b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
index 7279ea6..5885381 100644
--- a/modules/platforms/cpp/odbc/src/config/connection_info.cpp
+++ b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
@@ -766,7 +766,7 @@ namespace ignite
 #ifdef SQL_MULTIPLE_ACTIVE_TXN
                 // A character string: "Y" if the driver supports more than one active transaction at the same time,
                 // "N" if only one transaction can be active at any time.
-                strParams[SQL_MULTIPLE_ACTIVE_TXN] = "N";
+                strParams[SQL_MULTIPLE_ACTIVE_TXN] = "Y";
 #endif // SQL_MULTIPLE_ACTIVE_TXN
 
 #ifdef SQL_ORDER_BY_COLUMNS_IN_SELECT
@@ -1596,7 +1596,7 @@ namespace ignite
                 // SQL_TXN_REPEATABLE_READ = Dirty reads and nonrepeatable reads are not possible. Phantoms are possible
                 // SQL_TXN_SERIALIZABLE = Transactions are serializable. Serializable transactions do not allow dirty
                 //     reads, nonrepeatable reads, or phantoms.
-                intParams[SQL_DEFAULT_TXN_ISOLATION] = 0;
+                intParams[SQL_DEFAULT_TXN_ISOLATION] = SQL_TXN_REPEATABLE_READ;
 #endif // SQL_DEFAULT_TXN_ISOLATION
 
 #ifdef SQL_DROP_ASSERTION
@@ -2170,7 +2170,7 @@ namespace ignite
                 // SQL_ATTR_TXN_ISOLATION attribute. For more information, see SQLSetConnectAttr Function.
                 // An SQL-92 Entry level-conformant driver will always return SQL_TXN_SERIALIZABLE as supported.
                 // A FIPS Transitional level-conformant driver will always return all of these options as supported.
-                intParams[SQL_TXN_ISOLATION_OPTION] = 0;
+                intParams[SQL_TXN_ISOLATION_OPTION] = SQL_TXN_REPEATABLE_READ;
 #endif // SQL_TXN_ISOLATION_OPTION
 
 #ifdef SQL_UNION
@@ -2312,7 +2312,7 @@ namespace ignite
 
 #ifdef SQL_TXN_CAPABLE
                 // Describs the transaction support in the driver or data source.
-                shortParams[SQL_TXN_CAPABLE] = SQL_TC_NONE;
+                shortParams[SQL_TXN_CAPABLE] = SQL_TC_DDL_COMMIT;
 #endif // SQL_TXN_CAPABLE
 
 #ifdef SQL_QUOTED_IDENTIFIER_CASE

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/config/connection_string_parser.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/connection_string_parser.cpp b/modules/platforms/cpp/odbc/src/config/connection_string_parser.cpp
index d23c2cb..7f7c2f4 100644
--- a/modules/platforms/cpp/odbc/src/config/connection_string_parser.cpp
+++ b/modules/platforms/cpp/odbc/src/config/connection_string_parser.cpp
@@ -24,6 +24,7 @@
 #include "ignite/odbc/ssl/ssl_mode.h"
 #include "ignite/odbc/config/connection_string_parser.h"
 #include "ignite/odbc/config/config_tools.h"
+#include "ignite/odbc/nested_tx_mode.h"
 
 namespace ignite
 {
@@ -51,6 +52,7 @@ namespace ignite
             const std::string ConnectionStringParser::Key::sslCaFile              = "ssl_ca_file";
             const std::string ConnectionStringParser::Key::user                   = "user";
             const std::string ConnectionStringParser::Key::password               = "password";
+            const std::string ConnectionStringParser::Key::nestedTxMode           = "nested_tx_mode";
 
             ConnectionStringParser::ConnectionStringParser(Configuration& cfg):
                 cfg(cfg)
@@ -424,6 +426,23 @@ namespace ignite
                 {
                     cfg.SetPassword(value);
                 }
+                else if (lKey == Key::nestedTxMode)
+                {
+                    NestedTxMode::Type mode = NestedTxMode::FromString(value);
+
+                    if (mode == NestedTxMode::AI_UNKNOWN)
+                    {
+                        if (diag)
+                        {
+                            diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+                                "Specified nested transaction mode is not supported. Default value used ('error').");
+                        }
+
+                        return;
+                    }
+
+                    cfg.SetNestedTxMode(mode);
+                }
                 else if (diag)
                 {
                     std::stringstream stream;

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/connection.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/connection.cpp b/modules/platforms/cpp/odbc/src/connection.cpp
index 894efb7..5538549 100644
--- a/modules/platforms/cpp/odbc/src/connection.cpp
+++ b/modules/platforms/cpp/odbc/src/connection.cpp
@@ -25,6 +25,7 @@
 
 #include "ignite/odbc/log.h"
 #include "ignite/odbc/utility.h"
+#include "ignite/odbc/environment.h"
 #include "ignite/odbc/statement.h"
 #include "ignite/odbc/connection.h"
 #include "ignite/odbc/message.h"
@@ -54,10 +55,12 @@ namespace ignite
 {
     namespace odbc
     {
-        Connection::Connection() :
+        Connection::Connection(Environment* env) :
+            env(env),
             socket(),
             timeout(0),
             loginTimeout(SocketClient::DEFALT_CONNECT_TIMEOUT),
+            autoCommit(true),
             parser(),
             config(),
             info(config)
@@ -186,6 +189,11 @@ namespace ignite
             IGNITE_ODBC_API_CALL(InternalRelease());
         }
 
+        void Connection::Deregister()
+        {
+            env->DeregisterConnection(this);
+        }
+
         SqlResult::Type Connection::InternalRelease()
         {
             if (socket.get() == 0)
@@ -367,6 +375,11 @@ namespace ignite
             return config;
         }
 
+        bool Connection::IsAutoCommit()
+        {
+            return autoCommit;
+        }
+
         diagnostic::DiagnosticRecord Connection::CreateStatusRecord(SqlState::Type sqlState,
             const std::string& message, int32_t rowNum, int32_t columnNum)
         {
@@ -380,6 +393,37 @@ namespace ignite
 
         SqlResult::Type Connection::InternalTransactionCommit()
         {
+            std::string schema = config.GetSchema();
+
+            app::ParameterSet empty;
+
+            QueryExecuteRequest req(schema, "COMMIT", empty, timeout, autoCommit);
+            QueryExecuteResponse rsp;
+
+            try
+            {
+                bool sent = SyncMessage(req, rsp, timeout);
+
+                if (!sent)
+                {
+                    AddStatusRecord(SqlState::S08S01_LINK_FAILURE, "Failed to send commit request.");
+
+                    return SqlResult::AI_ERROR;
+                }
+            }
+            catch (const OdbcError& err)
+            {
+                AddStatusRecord(err);
+
+                return SqlResult::AI_ERROR;
+            }
+            catch (const IgniteError& err)
+            {
+                AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, err.GetText());
+
+                return SqlResult::AI_ERROR;
+            }
+
             return SqlResult::AI_SUCCESS;
         }
 
@@ -390,10 +434,38 @@ namespace ignite
 
         SqlResult::Type Connection::InternalTransactionRollback()
         {
-            AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
-                "Rollback operation is not supported.");
+            std::string schema = config.GetSchema();
+
+            app::ParameterSet empty;
 
-            return SqlResult::AI_ERROR;
+            QueryExecuteRequest req(schema, "ROLLBACK", empty, timeout, autoCommit);
+            QueryExecuteResponse rsp;
+
+            try
+            {
+                bool sent = SyncMessage(req, rsp, timeout);
+
+                if (!sent)
+                {
+                    AddStatusRecord(SqlState::S08S01_LINK_FAILURE, "Failed to send rollback request.");
+
+                    return SqlResult::AI_ERROR;
+                }
+            }
+            catch (const OdbcError& err)
+            {
+                AddStatusRecord(err);
+
+                return SqlResult::AI_ERROR;
+            }
+            catch (const IgniteError& err)
+            {
+                AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, err.GetText());
+
+                return SqlResult::AI_ERROR;
+            }
+
+            return SqlResult::AI_SUCCESS;
         }
 
         void Connection::GetAttribute(int attr, void* buf, SQLINTEGER bufLen, SQLINTEGER* valueLen)
@@ -452,7 +524,10 @@ namespace ignite
                 {
                     SQLUINTEGER *val = reinterpret_cast<SQLUINTEGER*>(buf);
 
-                    *val = SQL_AUTOCOMMIT_ON;
+                    *val = autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
+
+                    if (valueLen)
+                        *valueLen = SQL_IS_INTEGER;
 
                     break;
                 }
@@ -507,10 +582,17 @@ namespace ignite
 
                 case SQL_ATTR_AUTOCOMMIT:
                 {
-                    SQLUINTEGER val = static_cast<SQLUINTEGER>(reinterpret_cast<ptrdiff_t>(value));
+                    SQLUINTEGER mode = static_cast<SQLUINTEGER>(reinterpret_cast<ptrdiff_t>(value));
+
+                    if (mode != SQL_AUTOCOMMIT_ON && mode != SQL_AUTOCOMMIT_OFF)
+                    {
+                        AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+                            "Specified attribute is not supported.");
 
-                    if (val != SQL_AUTOCOMMIT_ON)
                         return SqlResult::AI_ERROR;
+                    }
+
+                    autoCommit = mode == SQL_AUTOCOMMIT_ON;
 
                     break;
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp b/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
index 143d949..6de0716 100644
--- a/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
@@ -52,6 +52,11 @@ namespace ignite
             {
                 AddStatusRecord(err.GetStatus(), err.GetErrorMessage(), 0, 0);
             }
+
+            void DiagnosableAdapter::AddStatusRecord(const DiagnosticRecord& rec)
+            {
+                diagnosticRecords.AddStatusRecord(rec);
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/dsn_config.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/dsn_config.cpp b/modules/platforms/cpp/odbc/src/dsn_config.cpp
index 1307d7e..dcdb8f4 100644
--- a/modules/platforms/cpp/odbc/src/dsn_config.cpp
+++ b/modules/platforms/cpp/odbc/src/dsn_config.cpp
@@ -212,6 +212,11 @@ namespace ignite
 
             if (password.IsSet() && !config.IsPasswordSet())
                 config.SetPassword(password.GetValue());
+
+            SettableValue<std::string> nestedTxModeStr = ReadDsnString(dsn, ConnectionStringParser::Key::nestedTxMode);
+
+            if (nestedTxModeStr.IsSet() && !config.IsNestedTxModeSet())
+                config.SetNestedTxMode(NestedTxMode::FromString(nestedTxModeStr.GetValue(), config.GetNestedTxMode()));
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/environment.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/environment.cpp b/modules/platforms/cpp/odbc/src/environment.cpp
index 417fedc..5a2ac4f 100644
--- a/modules/platforms/cpp/odbc/src/environment.cpp
+++ b/modules/platforms/cpp/odbc/src/environment.cpp
@@ -25,7 +25,8 @@ namespace ignite
 {
     namespace odbc
     {
-        Environment::Environment() : 
+        Environment::Environment() :
+            connections(),
             odbcVersion(SQL_OV_ODBC3),
             odbcNts(SQL_TRUE)
         {
@@ -46,9 +47,14 @@ namespace ignite
             return connection;
         }
 
+        void Environment::DeregisterConnection(Connection* conn)
+        {
+            connections.erase(conn);
+        }
+
         SqlResult::Type Environment::InternalCreateConnection(Connection*& connection)
         {
-            connection = new Connection;
+            connection = new Connection(this);
 
             if (!connection)
             {
@@ -57,6 +63,8 @@ namespace ignite
                 return SqlResult::AI_ERROR;
             }
 
+            connections.insert(connection);
+
             return SqlResult::AI_SUCCESS;
         }
 
@@ -67,7 +75,25 @@ namespace ignite
 
         SqlResult::Type Environment::InternalTransactionCommit()
         {
-            return SqlResult::AI_SUCCESS;
+            SqlResult::Type res = SqlResult::AI_SUCCESS;
+
+            for (ConnectionSet::iterator it = connections.begin(); it != connections.end(); ++it)
+            {
+                Connection* conn = *it;
+
+                conn->TransactionCommit();
+
+                diagnostic::DiagnosticRecordStorage& diag = conn->GetDiagnosticRecords();
+
+                if (diag.GetStatusRecordsNumber() > 0)
+                {
+                    AddStatusRecord(diag.GetStatusRecord(1));
+
+                    res = SqlResult::AI_SUCCESS_WITH_INFO;
+                }
+            }
+
+            return res;
         }
 
         void Environment::TransactionRollback()
@@ -77,10 +103,25 @@ namespace ignite
 
         SqlResult::Type Environment::InternalTransactionRollback()
         {
-            AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
-                "Rollback operation is not supported.");
+            SqlResult::Type res = SqlResult::AI_SUCCESS;
 
-            return SqlResult::AI_ERROR;
+            for (ConnectionSet::iterator it = connections.begin(); it != connections.end(); ++it)
+            {
+                Connection* conn = *it;
+
+                conn->TransactionRollback();
+
+                diagnostic::DiagnosticRecordStorage& diag = conn->GetDiagnosticRecords();
+
+                if (diag.GetStatusRecordsNumber() > 0)
+                {
+                    AddStatusRecord(diag.GetStatusRecord(1));
+
+                    res = SqlResult::AI_SUCCESS_WITH_INFO;
+                }
+            }
+
+            return res;
         }
 
         void Environment::SetAttribute(int32_t attr, void* value, int32_t len)

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/message.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/message.cpp b/modules/platforms/cpp/odbc/src/message.cpp
index 5b909b8..5730842 100644
--- a/modules/platforms/cpp/odbc/src/message.cpp
+++ b/modules/platforms/cpp/odbc/src/message.cpp
@@ -82,15 +82,18 @@ namespace ignite
             {
                 utility::WriteString(writer, config.GetUser());
                 utility::WriteString(writer, config.GetPassword());
+
+                writer.WriteInt8(config.GetNestedTxMode());
             }
         }
 
         QueryExecuteRequest::QueryExecuteRequest(const std::string& schema, const std::string& sql,
-            const app::ParameterSet& params, int32_t timeout):
+            const app::ParameterSet& params, int32_t timeout, bool autoCommit):
             schema(schema),
             sql(sql),
             params(params),
-            timeout(timeout)
+            timeout(timeout),
+            autoCommit(autoCommit)
         {
             // No-op.
         }
@@ -115,17 +118,21 @@ namespace ignite
 
             if (ver >= ProtocolVersion::VERSION_2_3_2)
                 writer.WriteInt32(timeout);
+
+            if (ver >= ProtocolVersion::VERSION_2_5_0)
+                writer.WriteBool(autoCommit);
         }
 
         QueryExecuteBatchtRequest::QueryExecuteBatchtRequest(const std::string& schema, const std::string& sql,
-            const app::ParameterSet& params, SqlUlen begin, SqlUlen end, bool last, int32_t timeout):
+            const app::ParameterSet& params, SqlUlen begin, SqlUlen end, bool last, int32_t timeout, bool autoCommit) :
             schema(schema),
             sql(sql),
             params(params),
             begin(begin),
             end(end),
             last(last),
-            timeout(timeout)
+            timeout(timeout),
+            autoCommit(autoCommit)
         {
             // No-op.
         }
@@ -150,6 +157,9 @@ namespace ignite
 
             if (ver >= ProtocolVersion::VERSION_2_3_2)
                 writer.WriteInt32(timeout);
+
+            if (ver >= ProtocolVersion::VERSION_2_5_0)
+                writer.WriteBool(autoCommit);
         }
 
         QueryCloseRequest::QueryCloseRequest(int64_t queryId): queryId(queryId)

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/nested_tx_mode.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/nested_tx_mode.cpp b/modules/platforms/cpp/odbc/src/nested_tx_mode.cpp
new file mode 100644
index 0000000..e4e6118
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/nested_tx_mode.cpp
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ignite/odbc/nested_tx_mode.h"
+#include "ignite/common/utils.h"
+
+namespace
+{
+    using ignite::odbc::NestedTxMode;
+    NestedTxMode::Type validValues0[] = {
+        NestedTxMode::AI_COMMIT,
+        NestedTxMode::AI_IGNORE,
+        NestedTxMode::AI_ERROR
+    };
+
+    NestedTxMode::ModeSet validValues(validValues0, validValues0 + (sizeof(validValues0) / sizeof(validValues0[0])));
+}
+
+
+namespace ignite
+{
+    namespace odbc
+    {
+        NestedTxMode::Type NestedTxMode::FromString(const std::string& str, Type dflt)
+        {
+            std::string lower = common::ToLower(str);
+
+            if (lower == "commit")
+                return AI_COMMIT;
+
+            if (lower == "ignore")
+                return AI_IGNORE;
+
+            if (lower == "error")
+                return AI_ERROR;
+
+            return dflt;
+        }
+
+        std::string NestedTxMode::ToString(Type value)
+        {
+            switch (value)
+            {
+                case AI_COMMIT:
+                    return "commit";
+
+                case AI_IGNORE:
+                    return "ignore";
+
+                case AI_ERROR:
+                    return "error";
+
+                default:
+                    break;
+            }
+
+            return "default";
+        }
+
+        const NestedTxMode::ModeSet& NestedTxMode::GetValidValues()
+        {
+            return validValues;
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/odbc.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/odbc.cpp b/modules/platforms/cpp/odbc/src/odbc.cpp
index 3aad52f..5b37da3 100644
--- a/modules/platforms/cpp/odbc/src/odbc.cpp
+++ b/modules/platforms/cpp/odbc/src/odbc.cpp
@@ -204,6 +204,8 @@ namespace ignite
         if (!connection)
             return SQL_INVALID_HANDLE;
 
+        connection->Deregister();
+
         delete connection;
 
         return SQL_SUCCESS;

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/query/batch_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/batch_query.cpp b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
index 8dada3c..1256c94 100644
--- a/modules/platforms/cpp/odbc/src/query/batch_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
@@ -144,7 +144,9 @@ namespace ignite
             {
                 const std::string& schema = connection.GetSchema();
 
-                QueryExecuteBatchtRequest req(schema, sql, params, begin, end, last, timeout);
+                QueryExecuteBatchtRequest req(schema, sql, params, begin, end, last, timeout,
+                    connection.IsAutoCommit());
+
                 QueryExecuteBatchResponse rsp;
 
                 try

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/query/data_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/data_query.cpp b/modules/platforms/cpp/odbc/src/query/data_query.cpp
index 6974c7f..69208b8 100644
--- a/modules/platforms/cpp/odbc/src/query/data_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/data_query.cpp
@@ -206,7 +206,7 @@ namespace ignite
             {
                 const std::string& schema = connection.GetSchema();
 
-                QueryExecuteRequest req(schema, sql, params, timeout);
+                QueryExecuteRequest req(schema, sql, params, timeout, connection.IsAutoCommit());
                 QueryExecuteResponse rsp;
 
                 try

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/yardstick/config/mvcc/benchmark-mvcc-messages.sh
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/mvcc/benchmark-mvcc-messages.sh b/modules/yardstick/config/mvcc/benchmark-mvcc-messages.sh
new file mode 100644
index 0000000..32068d3
--- /dev/null
+++ b/modules/yardstick/config/mvcc/benchmark-mvcc-messages.sh
@@ -0,0 +1,98 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Configuration to measure increased messages load with mvcc turned on.
+#
+
+now0=`date +'%H%M%S'`
+
+# JVM options.
+JVM_OPTS=${JVM_OPTS}" -DIGNITE_QUIET=false"
+
+# Uncomment to enable concurrent garbage collection (GC) if you encounter long GC pauses.
+JVM_OPTS=${JVM_OPTS}" \
+-Xms8g \
+-Xmx8g \
+-Xloggc:./gc${now0}.log \
+-XX:+PrintGCDetails \
+-verbose:gc \
+-XX:+UseParNewGC \
+-XX:+UseConcMarkSweepGC \
+-XX:+PrintGCDateStamps \
+"
+
+#Ignite version
+ver="RELEASE-"
+
+# List of default probes.
+# Add DStatProbe or VmStatProbe if your OS supports it (e.g. if running on Linux).
+BENCHMARK_DEFAULT_PROBES=ThroughputLatencyProbe,PercentileProbe,DStatProbe
+
+# Packages where the specified benchmark is searched by reflection mechanism.
+BENCHMARK_PACKAGES=org.yardstickframework,org.apache.ignite.yardstick
+
+# Flag which indicates to restart the servers before every benchmark execution.
+RESTART_SERVERS=true
+
+# Probe point writer class name.
+# BENCHMARK_WRITER=
+
+# The benchmark is designed to run with 1 client node (driver itself) and many (4 for instance) server nodes.
+SERVER_HOSTS=localhost,localhost,localhost,localhost
+DRIVER_HOSTS=localhost
+
+# Remote username.
+# REMOTE_USER=
+
+# Number of nodes, used to wait for the specified number of nodes to start.
+nodesNum=$((`echo ${SERVER_HOSTS} | tr ',' '\n' | wc -l` + `echo ${DRIVER_HOSTS} | tr ',' '\n' | wc -l`))
+
+# Warmup.
+w=30
+
+# Duration.
+d=300
+
+# Threads count.
+t=1
+
+# Sync mode.
+sm=FULL_SYNC
+
+# Parameters that should be the same across all the benchmarks launches.
+commonParams="-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -w ${w} -d ${d} \
+  -jdbc jdbc:ignite:thin://auto.find/ -t ${t} -sm ${sm} \
+  --clientNodesAfterId 100 \
+  -sn IgniteNode -cl --range 1000000 \
+  --atomic-mode TRANSACTIONAL"
+
+# Run configuration which contains all benchmarks.
+# Note that each benchmark is set to run for 300 seconds (5 min) with warm-up set to 60 seconds (1 minute).
+CONFIGS="\
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-off -b 0 --sqlRange 1, \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-on -b 0 --sqlRange 1 --mvcc, \
+  \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-off -b 0 --sqlRange 1000, \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-on -b 0 --sqlRange 1000 --mvcc, \
+  \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1-backup-2-mvcc-off -b 2 --sqlRange 1, \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1-backup-2-mvcc-on -b 2 --sqlRange 1 --mvcc, \
+  \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1000-backup-2-mvcc-off -b 2 --sqlRange 1000, \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1000-backup-2-mvcc-on -b 2 --sqlRange 1000 --mvcc, \
+"

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/yardstick/config/mvcc/benchmark-mvcc-processor.sh
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/mvcc/benchmark-mvcc-processor.sh b/modules/yardstick/config/mvcc/benchmark-mvcc-processor.sh
new file mode 100644
index 0000000..db45199
--- /dev/null
+++ b/modules/yardstick/config/mvcc/benchmark-mvcc-processor.sh
@@ -0,0 +1,95 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Configuration to compare mvcc on/off. This benchmark creates load on mvcc processor.
+#
+
+now0=`date +'%H%M%S'`
+
+# JVM options.
+JVM_OPTS=${JVM_OPTS}" -DIGNITE_QUIET=false"
+
+# Uncomment to enable concurrent garbage collection (GC) if you encounter long GC pauses.
+JVM_OPTS=${JVM_OPTS}" \
+-Xms8g \
+-Xmx8g \
+-Xloggc:./gc${now0}.log \
+-XX:+PrintGCDetails \
+-verbose:gc \
+-XX:+UseParNewGC \
+-XX:+UseConcMarkSweepGC \
+-XX:+PrintGCDateStamps \
+"
+
+#Ignite version
+ver="RELEASE-"
+
+# List of default probes.
+# Add DStatProbe or VmStatProbe if your OS supports it (e.g. if running on Linux).
+BENCHMARK_DEFAULT_PROBES=ThroughputLatencyProbe,PercentileProbe,DStatProbe
+
+# Packages where the specified benchmark is searched by reflection mechanism.
+BENCHMARK_PACKAGES=org.yardstickframework,org.apache.ignite.yardstick
+
+# Flag which indicates to restart the servers before every benchmark execution.
+RESTART_SERVERS=true
+
+# Probe point writer class name.
+# BENCHMARK_WRITER=
+
+# The benchmark is designed to run with 4 client nodes (drivers) and 1 server node.
+SERVER_HOSTS=localhost
+DRIVER_HOSTS=localhost,localhost,localhost,localhost
+
+# Remote username.
+# REMOTE_USER=
+
+# Number of nodes, used to wait for the specified number of nodes to start.
+nodesNum=$((`echo ${SERVER_HOSTS} | tr ',' '\n' | wc -l` + `echo ${DRIVER_HOSTS} | tr ',' '\n' | wc -l`))
+
+# Warmup.
+w=30
+
+# Duration.
+d=300
+
+# Threads count.
+t=16
+
+# Sync mode.
+sm=FULL_SYNC
+
+# Parameters that should be the same across all the benchmarks launches.
+commonParams="-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -w ${w} -d ${d} \
+  -jdbc jdbc:ignite:thin://auto.find/ -t ${t} -sm ${sm} \
+  --clientNodesAfterId 100 \
+  -sn IgniteNode -cl --range 1000000 \
+  --atomic-mode TRANSACTIONAL"
+
+# Run configuration which contains all benchmarks.
+# Note that each benchmark is set to run for 300 seconds (5 min) with warm-up set to 60 seconds (1 minute).
+CONFIGS="\
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-off -b 0 --sqlRange 1, \
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-on -b 0 --sqlRange 1 --mvcc, \
+  \
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-25-backup-0-mvcc-off -b 0 --sqlRange 25, \
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-25-backup-0-mvcc-on -b 0 --sqlRange 25 --mvcc, \
+  \
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-off -b 0 --sqlRange 1000, \
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-on -b 0 --sqlRange 1000 --mvcc \
+"

http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/yardstick/config/mvcc/benchmark-mvcc-updates-contention.sh
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/mvcc/benchmark-mvcc-updates-contention.sh b/modules/yardstick/config/mvcc/benchmark-mvcc-updates-contention.sh
new file mode 100644
index 0000000..0a92bce
--- /dev/null
+++ b/modules/yardstick/config/mvcc/benchmark-mvcc-updates-contention.sh
@@ -0,0 +1,96 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Configuration to measure performance of concurrent sql updates with contention.
+# Update keys are shared among the threads/hosts.
+#
+now0=`date +'%H%M%S'`
+
+# JVM options.
+JVM_OPTS=${JVM_OPTS}" -DIGNITE_QUIET=false"
+
+# Uncomment to enable concurrent garbage collection (GC) if you encounter long GC pauses.
+JVM_OPTS=${JVM_OPTS}" \
+-Xms8g \
+-Xmx8g \
+-Xloggc:./gc${now0}.log \
+-XX:+PrintGCDetails \
+-verbose:gc \
+-XX:+UseParNewGC \
+-XX:+UseConcMarkSweepGC \
+-XX:+PrintGCDateStamps \
+"
+
+#Ignite version
+ver="RELEASE-"
+
+# List of default probes.
+# Add DStatProbe or VmStatProbe if your OS supports it (e.g. if running on Linux).
+BENCHMARK_DEFAULT_PROBES=ThroughputLatencyProbe,PercentileProbe,DStatProbe
+
+# Packages where the specified benchmark is searched by reflection mechanism.
+BENCHMARK_PACKAGES=org.yardstickframework,org.apache.ignite.yardstick
+
+# Flag which indicates to restart the servers before every benchmark execution.
+RESTART_SERVERS=true
+
+# Probe point writer class name.
+# BENCHMARK_WRITER=
+
+# The benchmark is designed to run with 4 client node (drivers) and several (2 for instance) server nodes
+SERVER_HOSTS=localhost,localhost
+DRIVER_HOSTS=localhost,localhost,localhost,localhost
+
+# Remote username.
+# REMOTE_USER=
+
+# Number of nodes, used to wait for the specified number of nodes to start.
+nodesNum=$((`echo ${SERVER_HOSTS} | tr ',' '\n' | wc -l` + `echo ${DRIVER_HOSTS} | tr ',' '\n' | wc -l`))
+
+# Warmup.
+w=30
+
+# Duration.
+d=300
+
+# Threads count.
+t=16
+
+# Sync mode.
+sm=FULL_SYNC
+
+# Parameters that should be the same across all the benchmarks launches.
+commonParams="-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -w ${w} -d ${d} \
+  -jdbc jdbc:ignite:thin://auto.find/ -t ${t} -sm ${sm} \
+  --clientNodesAfterId 100 \
+  -sn IgniteNode -cl \
+  --range 1000000 --mvcc-contention-range 10000 \
+  --atomic-mode TRANSACTIONAL"
+
+# Run configuration which contains all benchmarks.
+# Note that each benchmark is set to run for 300 seconds (5 min) with warm-up set to 60 seconds (1 minute).
+CONFIGS="\
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-off -b 0 --sqlRange 1, \
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-on -b 0 --sqlRange 1 --mvcc, \
+  \
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-25-backup-0-mvcc-off -b 0 --sqlRange 25, \
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-25-backup-0-mvcc-on -b 0 --sqlRange 25 --mvcc, \
+  \
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-off -b 0 --sqlRange 1000, \
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-on -b 0 --sqlRange 1000 --mvcc \
+"