Skip to content

fix(sessions): skip unnecessary FOR UPDATE lock on app/user state rows#4730

Open
giulio-leone wants to merge 3 commits intogoogle:mainfrom
giulio-leone:fix/skip-unnecessary-for-update-lock
Open

fix(sessions): skip unnecessary FOR UPDATE lock on app/user state rows#4730
giulio-leone wants to merge 3 commits intogoogle:mainfrom
giulio-leone:fix/skip-unnecessary-for-update-lock

Conversation

@giulio-leone
Copy link

The database session service currently takes FOR UPDATE locks on app and user state rows even when there are no deltas to write. This causes unnecessary lock contention under concurrent requests.

This PR skips the lock acquisition when there are no state deltas to persist.

Supersedes #4656 (closed due to CLA issue, now resolved).

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the concurrency and performance of the database session service by optimizing the acquisition of FOR UPDATE locks. By pre-analyzing state changes, the system now intelligently skips unnecessary locks on app and user state rows, thereby reducing contention and improving the efficiency of concurrent append_event operations.

Highlights

  • Optimized Database Locking: Introduced logic to pre-analyze state deltas within the append_event function, allowing the system to determine if app or user state modifications are actually present before attempting to acquire FOR UPDATE locks.
  • Reduced Lock Contention: Enabled conditional acquisition of FOR UPDATE locks on app and user state rows, preventing unnecessary serialization of concurrent append_event calls when no app or user state changes are required.
  • Improved Robustness: Added a null check to the session state update logic, ensuring state_deltas exists before attempting to access its 'session' key, preventing potential errors.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/google/adk/sessions/database_session_service.py
    • Added new code to the append_event method to extract and analyze state deltas, determining if 'app' or 'user' scoped state changes are present.
    • Modified the condition for updating session-scoped state to include a null check for state_deltas, making the operation more robust.
Activity
  • No specific activity has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@adk-bot adk-bot added the services [Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc label Mar 6, 2026
@adk-bot
Copy link
Collaborator

adk-bot commented Mar 6, 2026

Response from ADK Triaging Agent

Hello @giulio-leone, thank you for your contribution!

Could you please add a testing plan section to your PR description to describe how you tested these changes? This will help the reviewers to better understand and verify your fix.

You can find more information about the contribution guidelines here: https://github.com/google/adk-python/blob/main/CONTRIBUTING.md#requirement-for-prs

Thanks!

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a valuable performance optimization by skipping unnecessary FOR UPDATE locks on app and user state rows during event appends when there are no state deltas. The approach of pre-analyzing state deltas to conditionally acquire locks is sound and well-implemented. The accompanying changes and tests are appropriate. I have one minor suggestion to improve code clarity by removing a redundant check.

@giulio-leone giulio-leone force-pushed the fix/skip-unnecessary-for-update-lock branch from 91f19fd to 1ef2fcd Compare March 6, 2026 16:13
giulio-leone and others added 3 commits March 6, 2026 18:14
DatabaseSessionService.append_event() unconditionally acquires SELECT ...
FOR UPDATE on both app_states and user_states tables, even when the event
carries no state delta for those scopes.

Since app_states is keyed by app_name alone, all concurrent append_event
calls within the same app serialize on this single row lock, even when
they only carry session-scoped state (the vast majority of events).

Fix: pre-analyze the event's state_delta before acquiring locks and only
use FOR UPDATE when the corresponding scope actually has changes. This
also avoids a redundant call to extract_state_delta later in the method.

Fixes google#4655
Addresses review feedback: use a single conditional expression instead
of separate variable initializations and if block.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@giulio-leone giulio-leone force-pushed the fix/skip-unnecessary-for-update-lock branch from 1ef2fcd to 8db8a51 Compare March 6, 2026 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

services [Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants