1+ /*
2+ * Copyright 2026 Google LLC
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+ package com .example .spanner ;
18+
19+ import com .google .cloud .spanner .DatabaseClient ;
20+ import com .google .cloud .spanner .DatabaseId ;
21+ import com .google .cloud .spanner .Options ;
22+ import com .google .cloud .spanner .ResultSet ;
23+ import com .google .cloud .spanner .Spanner ;
24+ import com .google .cloud .spanner .SpannerOptions ;
25+ import com .google .cloud .spanner .SpannerOptions .Builder .DefaultReadWriteTransactionOptions ;
26+ import com .google .cloud .spanner .Statement ;
27+ import com .google .spanner .v1 .TransactionOptions .IsolationLevel ;
28+ import com .google .spanner .v1 .TransactionOptions .ReadWrite .ReadLockMode ;
29+
30+ public class IsolationLevelAndReadLockModeSample {
31+
32+ // [START spanner_isolation_level]
33+ static void isolationLevelSetting (DatabaseId db ) {
34+ // The isolation level specified at the client-level will be applied to all
35+ // RW transactions.
36+ DefaultReadWriteTransactionOptions transactionOptions =
37+ DefaultReadWriteTransactionOptions .newBuilder ()
38+ .setIsolationLevel (IsolationLevel .SERIALIZABLE )
39+ .build ();
40+ SpannerOptions options =
41+ SpannerOptions .newBuilder ()
42+ .setDefaultTransactionOptions (transactionOptions )
43+ .build ();
44+ Spanner spanner = options .getService ();
45+ DatabaseClient dbClient = spanner .getDatabaseClient (db );
46+ dbClient
47+ // The isolation level specified at the transaction-level takes precedence
48+ // over the isolation level configured at the client-level.
49+ .readWriteTransaction (Options .isolationLevel (IsolationLevel .REPEATABLE_READ ))
50+ .run (transaction -> {
51+ // Read an AlbumTitle.
52+ String selectSql =
53+ "SELECT AlbumTitle from Albums WHERE SingerId = 1 and AlbumId = 1" ;
54+ String title = null ;
55+ try (ResultSet resultSet = transaction .executeQuery (Statement .of (selectSql ))) {
56+ if (resultSet .next ()) {
57+ title = resultSet .getString ("AlbumTitle" );
58+ }
59+ }
60+ System .out .printf ("Current album title: %s\n " , title );
61+
62+ // Update the title.
63+ String updateSql =
64+ "UPDATE Albums "
65+ + "SET AlbumTitle = 'New Album Title' "
66+ + "WHERE SingerId = 1 and AlbumId = 1" ;
67+ long rowCount = transaction .executeUpdate (Statement .of (updateSql ));
68+ System .out .printf ("%d record updated.\n " , rowCount );
69+ return null ;
70+ });
71+ }
72+ // [END spanner_isolation_level]
73+
74+ // [START spanner_read_lock_mode]
75+ static void readLockModeSetting (DatabaseId db ) {
76+ // The read lock mode specified at the client-level will be applied to all
77+ // RW transactions.
78+ DefaultReadWriteTransactionOptions transactionOptions =
79+ DefaultReadWriteTransactionOptions .newBuilder ()
80+ .setReadLockMode (ReadLockMode .OPTIMISTIC )
81+ .build ();
82+ SpannerOptions options =
83+ SpannerOptions .newBuilder ()
84+ .setDefaultTransactionOptions (transactionOptions )
85+ .build ();
86+ Spanner spanner = options .getService ();
87+ DatabaseClient dbClient = spanner .getDatabaseClient (db );
88+ dbClient
89+ // The read lock mode specified at the transaction-level takes precedence
90+ // over the read lock mode configured at the client-level.
91+ .readWriteTransaction (Options .readLockMode (ReadLockMode .PESSIMISTIC ))
92+ .run (transaction -> {
93+ // Read an AlbumTitle.
94+ String selectSql =
95+ "SELECT AlbumTitle from Albums WHERE SingerId = 1 and AlbumId = 1" ;
96+ String title = null ;
97+ try (ResultSet resultSet = transaction .executeQuery (Statement .of (selectSql ))) {
98+ if (resultSet .next ()) {
99+ title = resultSet .getString ("AlbumTitle" );
100+ }
101+ }
102+ System .out .printf ("Current album title: %s\n " , title );
103+
104+ // Update the title.
105+ String updateSql =
106+ "UPDATE Albums "
107+ + "SET AlbumTitle = 'New Album Title' "
108+ + "WHERE SingerId = 1 and AlbumId = 1" ;
109+ long rowCount = transaction .executeUpdate (Statement .of (updateSql ));
110+ System .out .printf ("%d record updated.\n " , rowCount );
111+ return null ;
112+ });
113+ }
114+ // [END spanner_read_lock_mode]
115+ }
0 commit comments