[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["很难理解","hardToUnderstand","thumb-down"],["信息或示例代码不正确","incorrectInformationOrSampleCode","thumb-down"],["没有我需要的信息/示例","missingTheInformationSamplesINeed","thumb-down"],["翻译问题","translationIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-08-21。"],[],[],null,["# Timestamp bounds\n\nIntroduction\n------------\n\nWhen reading data in Spanner in either a\n[read-only transaction](/spanner/docs/transactions#read-only_transactions) or a\n[single read call](/spanner/docs/reads), you can set a **timestamp bound**, which\ntells Spanner how to choose a timestamp at which to read the data.\n\nWhy set a timestamp bound? If your database is geographically distributed (that\nis, you created your Spanner instance using a multi-region instance\nconfiguration), and your application can tolerate some staleness when reading\ndata, then you can get latency benefits from executing a stale read instead of a\nstrong read. (Learn more about these read types in [Reads](/spanner/docs/reads).)\n\nTimestamp bound types\n---------------------\n\nThe types of timestamp bound are:\n\n- Strong (the default): read the latest data.\n- Bounded staleness: read a version of the data that's no staler than a bound.\n- Exact staleness: read the version of the data at an exact timestamp, e.g. a point in time in the past, though you can specify a timestamp for a time that hasn't passed yet. (If you specify a timestamp in the future, Spanner will wait for that timestamp before serving the read.)\n\nNotes:\n\n- Although reads using these timestamp bound modes are not part of a read-write\n transaction, they can block waiting for concurrent read-write transactions to\n commit. Bounded staleness reads attempt to pick a timestamp to avoid blocking,\n but may still block.\n\n- Stale reads (i.e. using the bounded or exact staleness types) have the maximum\n performance benefit at longest staleness intervals. Use a minimum staleness of\n 10 seconds to get a benefit.\n\n- Spanner keeps track of a database's [`earliest_version_time`](/spanner/docs/reference/rest/v1/projects.instances.databases#Database.FIELDS.earliest_version_time), which specifies the earliest time at which past versions of data can be read. You cannot read at a timestamp before the earliest version time.\n\nThe Spanner timestamp bound types are explained in more detail below.\n\n### Strong\n\nSpanner provides a bound type for strong reads. Strong reads are\nguaranteed to see the effects of all transactions that have committed before the\nstart of the read. Furthermore, all rows yielded by a single read are consistent\nwith each other - if any part of the read observes a transaction, all parts of\nthe read see the transaction.\n\nStrong reads are not repeatable: two consecutive strong read-only transactions\nmight return inconsistent results if there are concurrent writes. If consistency\nacross reads is required, the reads should be executed within the same\ntransaction or at an exact read timestamp.\n\n### Bounded staleness\n\nSpanner provides a bound type for bounded staleness. Bounded staleness\nmodes allow Spanner to pick the read timestamp, subject to a user-\nprovided staleness bound. Spanner chooses the newest timestamp within\nthe staleness bound that allows execution of the reads at the closest available\nreplica without blocking.\n\nAll rows yielded are consistent with each other - if any part of the read\nobserves a transaction, all parts of the read see the transaction. Boundedly\nstale reads are not repeatable: two stale reads, even if they use the\nsame staleness bound, can execute at different timestamps and thus return\ninconsistent results.\n\nBounded staleness reads are usually a little slower than comparable exact\nstaleness reads.\n| **Note:** If you're using bounded staleness with a read-only transaction, you can only use it with single-use read-only transactions, not with general-purpose read-only transactions.\n\n### Exact staleness\n\nSpanner provides a bound type for exact staleness. These timestamp\nbounds execute reads at a user-specified timestamp. Reads at a timestamp are\nguaranteed to see a consistent prefix of the global transaction history: they\nobserve modifications done by all transactions with a commit timestamp less than\nor equal to the read timestamp, and observe none of the modifications done by\ntransactions with a larger commit timestamp. They will block until all\nconflicting transactions that may be assigned commit timestamps less than or\nequal to the read timestamp have finished.\n\nThe timestamp can either be expressed as an absolute Spanner commit\ntimestamp or a staleness relative to the current time.\n\nThese modes do not require a \"negotiation phase\" to pick a timestamp. As a\nresult, they execute slightly faster than the equivalent boundedly stale\nconcurrency modes. On the other hand, boundedly stale reads usually return\nfresher results.\n\nMaximum timestamp staleness\n---------------------------\n\nSpanner continuously garbage collects deleted and overwritten data\nin the background to reclaim storage space. This process is known as **version\nGC** . Version GC reclaims versions after they expire past a database's [`version_retention_period`](/spanner/docs/reference/rest/v1/projects.instances.databases#Database.FIELDS.version_retention_period), which defaults to 1 hour, but can be configured up to 1 week.\nThis restriction also applies to in-progress reads and/or SQL queries\nwhose timestamp become too old while executing. Reads and SQL queries with\ntoo-old read timestamps fail with the error `FAILED_PRECONDITION`. The only\nexception is [Partition Read/Query](/spanner/docs/reads#read_data_in_parallel) with\npartition tokens, which will prevent garbage collection of expired data while\nthe session remains active."]]