@@ -101,10 +101,15 @@ THD *create_thd(const spectrum::Thread &spectrum_thread)
101101 } else {
102102 thd->query_id = (query_id_t )spectrum_thread.query_id ();
103103 }
104-
105104 return (thd);
106105}
107106
107+ void release_thd (THD *thd) {
108+ thd->release_resources ();
109+ Global_THD_manager::get_instance ()->remove_thd (thd);
110+ delete thd;
111+ }
112+
108113bool check_and_coalesce_trx_read_write (THD *thd, bool all) {
109114 Transaction_ctx::enum_trx_scope trx_scope =
110115 all ? Transaction_ctx::SESSION : Transaction_ctx::STMT;
@@ -603,6 +608,34 @@ class StorageNodeImpl final : public spectrum::StorageNode::Service {
603608 return grpc::Status::OK;
604609 }
605610
611+ ::grpc::Status Rollback (::grpc::ServerContext* context, const ::spectrum::RollbackRequest* request, ::spectrum::RollbackResponse* response) {
612+ THD *thd = create_thd (request->thread ());
613+ Transaction_ctx *trn_ctx = thd->get_transaction ();
614+ bool all = request->all ();
615+ bool real_trans = (all || !trn_ctx->is_active (Transaction_ctx::SESSION));
616+ spectrum_storage::THD_context *thd_storage_context = thd->spectrum_storage_context ();
617+
618+ sql_print_information (" Rollback[%d]: all=%d, real_trans=%d" , thd->spectrum_thread_id , all, real_trans);
619+
620+ if (check_and_coalesce_trx_read_write (thd, all)) {
621+ spectrum_log_open (thd);
622+ spectrum_log_rollback (thd, all, real_trans);
623+ } else {
624+ sql_print_information (" Rollback[%d]: skip spectrum log rollback for readonly transaction" , thd->spectrum_thread_id );
625+ }
626+
627+ ha_rollback_low (thd, all);
628+ thd_storage_context->set_prepared (false );
629+
630+ spectrum_log_close (thd);
631+
632+ if (real_trans) {
633+ trn_ctx->cleanup ();
634+ thd->tx_priority = 0 ;
635+ }
636+ return grpc::Status::OK;
637+ }
638+
606639 ::grpc::Status BeginAttachableTransaction (::grpc::ServerContext* context, const ::spectrum::BeginAttachableTransactionRequest* request, ::spectrum::BeginAttachableTransactionResponse* response) {
607640 THD *thd;
608641
@@ -932,7 +965,6 @@ class StorageReplicaNodeImpl final : public spectrum::StorageReplicaNode::Servic
932965 ha_prepare_low (thd, false );
933966 ha_commit_low (thd, false );
934967 }
935-
936968 ha_prepare_low (thd, all);
937969 thd_storage_context->set_prepared (true );
938970 return 0 ;
@@ -972,6 +1004,30 @@ class StorageReplicaNodeImpl final : public spectrum::StorageReplicaNode::Servic
9721004 return 0 ;
9731005 }
9741006
1007+ int Rollback (spectrum::Event &event) {
1008+ spectrum::RollbackRequest request;
1009+ google::protobuf::TextFormat::ParseFromString (event.body (), &request);
1010+
1011+ THD *thd = create_thd (request.thread ());
1012+ spectrum_storage::THD_context *thd_storage_context = thd->spectrum_storage_context ();
1013+ bool all = request.all ();
1014+ commit_id_t commit_id = request.commit_id ();
1015+
1016+ sql_print_information (" Rollback: all=%d, commit_id=%d" , all, commit_id);
1017+
1018+ close_thread_tables (thd);
1019+
1020+ ha_rollback_low (thd, all);
1021+ thd_storage_context->set_prepared (false );
1022+
1023+ spectrum_log_close (thd);
1024+
1025+ if (all) {
1026+ thd->mdl_context .release_transactional_locks ();
1027+ }
1028+ return 0 ;
1029+ }
1030+
9751031 ::grpc::Status InitReplicationStream (::grpc::ServerContext* context, const ::spectrum::InitReplicationStreamRequest* request, ::spectrum::InitReplicationStreamResponse* response) {
9761032 mysql_mutex_lock (&replication_lock);
9771033
@@ -1019,6 +1075,10 @@ class StorageReplicaNodeImpl final : public spectrum::StorageReplicaNode::Servic
10191075 Commit (event);
10201076 response.set_event_id (event.id ());
10211077 stream->Write (response);
1078+ } else if (event_type == spectrum::event_type_enum::ROLLBACK) {
1079+ Rollback (event);
1080+ response.set_event_id (event.id ());
1081+ stream->Write (response);
10221082 }
10231083
10241084 mysql_mutex_unlock (&replication_lock);
0 commit comments