Skip to content

Commit 6bd806f

Browse files
committed
bug mongo: Transaction does not keep its invariant. Hide it from users
Tests: протестировано CI commit_hash:01bc74240ad70b0db85b092fa56b361057c3b5e9
1 parent fea6d6c commit 6bd806f

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

mongo/include/userver/storages/mongo/pool.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,6 @@ class Pool {
5656
/// @throws storages::mongo::MongoException if failed to connect to the mongo server.
5757
void Ping();
5858

59-
/// @brief Begin a new transaction
60-
/// @return Transaction handle for executing operations within transaction context
61-
/// @throws MongoException if transaction cannot be started
62-
Transaction BeginTransaction() const;
63-
6459
/// @cond
6560
// For internal use only
6661
Pool(
@@ -81,6 +76,13 @@ class Pool {
8176
/// @endcond
8277

8378
private:
79+
// Note: transactions are broken. See tests for more info
80+
//
81+
/// @brief Begin a new transaction
82+
/// @return Transaction handle for executing operations within transaction context
83+
/// @throws MongoException if transaction cannot be started
84+
Transaction BeginTransaction() const;
85+
8486
std::shared_ptr<impl::PoolImpl> impl_;
8587
};
8688

mongo/src/storages/mongo/transaction_mongotest.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
USERVER_NAMESPACE_BEGIN
1313

14+
#if 0
15+
1416
namespace bson = formats::bson;
1517

1618
// NOLINTNEXTLINE(google-build-using-namespace)
@@ -273,4 +275,47 @@ UTEST_F(MongoTransaction, ParallelTrancactions) {
273275
EXPECT_THAT(found_docs, ::testing::ElementsAre(bson::MakeDoc("name", "test_user", "age", 30)));
274276
}
275277

278+
UTEST_F(MongoTransaction, InvalidSessionIdReproducer) {
279+
static const std::string kCollectionName = "test_invalid_session_id";
280+
281+
auto config = MakeTestPoolConfig();
282+
config.pool_settings.initial_size = 1;
283+
config.pool_settings.max_size = 3;
284+
config.pool_settings.idle_limit = 2;
285+
286+
auto pool = MakePool("userver_mongotest_invalid_session_id", config);
287+
288+
auto coll = pool.GetCollection(kCollectionName);
289+
290+
{
291+
std::vector<formats::bson::Document> docs;
292+
docs.reserve(10);
293+
for (int i = 0; i < 10; ++i) {
294+
docs.push_back(bson::MakeDoc("foo", "bar", "value", i));
295+
}
296+
coll.InsertMany(std::move(docs));
297+
}
298+
299+
using formats::bson::MakeDoc;
300+
301+
auto txn = pool.BeginTransaction();
302+
// GetCollection starts a transaction using client_1 from the pool
303+
auto coll_txn = txn.GetCollection(kCollectionName);
304+
305+
// Find uses the same client_1 from the pool because initial_size == 1
306+
// and returns a Cursor that holds this client
307+
//
308+
// TODO: transaction is not usable after that???
309+
auto cursor = coll.Find(MakeDoc("foo", "bar"));
310+
311+
// TODO: Must be fatal or must not compile: two cursors in the same transaction?
312+
auto cursor = coll.Find(MakeDoc("foo", "bar"));
313+
314+
// TODO: Must be fatal or must not compile: executing not in a transaction
315+
UASSERT_THROW( coll_txn.InsertOne(MakeDoc("foo", "bar", "value", 11)) );
316+
txn.Commit();
317+
}
318+
319+
#endif
320+
276321
USERVER_NAMESPACE_END

0 commit comments

Comments
 (0)