@@ -17,7 +17,7 @@ namespace {
1717// key - $1
1818// owner - $2
1919// timeout in seconds - $3
20- std::string MakeAcquireQuery (const std::string& table) {
20+ Query MakeAcquireQuery (const std::string& table) {
2121 static constexpr std::string_view kAcquireQueryFmt = R"(
2222 INSERT INTO {} AS t (key, owner, expiration_time) SELECT
2323 $1, $2, current_timestamp + make_interval(secs => $3)
@@ -35,19 +35,19 @@ std::string MakeAcquireQuery(const std::string& table) {
3535 WHERE (t.owner = $2) OR
3636 (t.expiration_time <= current_timestamp) RETURNING 1;
3737)" ;
38- return fmt::format (FMT_COMPILE (kAcquireQueryFmt ), table, table);
38+ return { fmt::format (FMT_COMPILE (kAcquireQueryFmt ), table, table), Query::Name{ " dist_lock_acquire " }} ;
3939}
4040
4141// key - $1
4242// owner - $2
43- std::string MakeReleaseQuery (const std::string& table) {
43+ Query MakeReleaseQuery (const std::string& table) {
4444 static constexpr std::string_view kReleaseQueryFmt = R"(
4545 DELETE FROM {}
4646 WHERE key = $1
4747 AND owner = $2
4848 RETURNING 1;
4949)" ;
50- return fmt::format (FMT_COMPILE (kReleaseQueryFmt ), table);
50+ return { fmt::format (FMT_COMPILE (kReleaseQueryFmt ), table), Query::Name{ " dist_lock_release " }} ;
5151}
5252
5353std::string MakeOwnerId (const std::string& prefix, const std::string& locker) {
@@ -79,17 +79,28 @@ void DistLockStrategy::UpdateCommandControl(CommandControl cc) {
7979void DistLockStrategy::Acquire (std::chrono::milliseconds lock_ttl, const std::string& locker_id) {
8080 const double timeout_seconds = lock_ttl.count () / 1000.0 ;
8181 auto cc_ptr = cc_.Read ();
82- auto result = cluster_->Execute (
83- ClusterHostType::kMaster ,
84- *cc_ptr,
85- acquire_query_,
86- lock_name_,
87- MakeOwnerId (owner_prefix_, locker_id),
88- timeout_seconds
89- );
90-
91- if (result.IsEmpty ()) {
92- throw dist_lock::LockIsAcquiredByAnotherHostException ();
82+
83+ try {
84+ auto result = cluster_->Execute (
85+ ClusterHostType::kMaster ,
86+ *cc_ptr,
87+ acquire_query_,
88+ lock_name_,
89+ MakeOwnerId (owner_prefix_, locker_id),
90+ timeout_seconds
91+ );
92+
93+ if (result.IsEmpty ()) {
94+ throw dist_lock::LockIsAcquiredByAnotherHostException ();
95+ }
96+ } catch (const TransactionRollback& exc) {
97+ if (exc.GetSqlState () == SqlState::kSerializationFailure ) {
98+ // Looks like the default transaction isolation is 'repeatable read' or 'serializable' and we were hit by
99+ // "could not serialize access due to concurrent update"
100+ throw dist_lock::LockIsAcquiredByAnotherHostException ();
101+ } else {
102+ throw ;
103+ }
93104 }
94105}
95106
0 commit comments