4141
4242import lombok .extern .slf4j .Slf4j ;
4343
44+ import org .springframework .transaction .support .TransactionTemplate ;
45+
4446import com .google .common .collect .Lists ;
4547
4648@ Slf4j
@@ -57,23 +59,27 @@ public class JdbcRegistryDataManager
5759
5860 private final JdbcRegistryDataChangeEventRepository jdbcRegistryDataChangeEventRepository ;
5961
62+ private final TransactionTemplate jdbcRegistryTransactionTemplate ;
63+
6064 private final List <RegistryRowChangeListener <JdbcRegistryDataDTO >> registryRowChangeListeners ;
6165
6266 private long lastDetectedJdbcRegistryDataChangeEventId = -1 ;
6367
6468 public JdbcRegistryDataManager (JdbcRegistryProperties registryProperties ,
6569 JdbcRegistryDataRepository jdbcRegistryDataRepository ,
66- JdbcRegistryDataChangeEventRepository jdbcRegistryDataChangeEventRepository ) {
70+ JdbcRegistryDataChangeEventRepository jdbcRegistryDataChangeEventRepository ,
71+ TransactionTemplate jdbcRegistryTransactionTemplate ) {
6772 this .registryProperties = registryProperties ;
6873 this .jdbcRegistryDataChangeEventRepository = jdbcRegistryDataChangeEventRepository ;
6974 this .jdbcRegistryDataRepository = jdbcRegistryDataRepository ;
75+ this .jdbcRegistryTransactionTemplate = jdbcRegistryTransactionTemplate ;
7076 this .registryRowChangeListeners = new CopyOnWriteArrayList <>();
71- this .lastDetectedJdbcRegistryDataChangeEventId =
72- jdbcRegistryDataChangeEventRepository .getMaxJdbcRegistryDataChangeEventId ();
7377 }
7478
7579 @ Override
7680 public void start () {
81+ this .lastDetectedJdbcRegistryDataChangeEventId =
82+ jdbcRegistryDataChangeEventRepository .getMaxJdbcRegistryDataChangeEventId ();
7783 JdbcRegistryThreadFactory .getDefaultSchedulerThreadExecutor ().scheduleWithFixedDelay (
7884 this ::detectJdbcRegistryDataChangeEvent ,
7985 registryProperties .getHeartbeatRefreshInterval ().toMillis (),
@@ -162,67 +168,73 @@ public void putJdbcRegistryData(Long clientId, String key, String value, DataTyp
162168 checkNotNull (key );
163169 checkNotNull (dataType );
164170
165- Optional <JdbcRegistryDataDTO > jdbcRegistryDataOptional = jdbcRegistryDataRepository .selectByKey (key );
166- if (jdbcRegistryDataOptional .isPresent ()) {
167- JdbcRegistryDataDTO jdbcRegistryData = jdbcRegistryDataOptional .get ();
168- if (!dataType .name ().equals (jdbcRegistryData .getDataType ())) {
169- throw new UnsupportedOperationException ("The data type: " + jdbcRegistryData .getDataType ()
170- + " of the key: " + key + " cannot be updated" );
171- }
171+ final Optional <JdbcRegistryDataDTO > jdbcRegistryDataOptional = jdbcRegistryDataRepository .selectByKey (key );
172172
173- if (DataType .EPHEMERAL .name ().equals (jdbcRegistryData .getDataType ())) {
174- if (!jdbcRegistryData .getClientId ().equals (clientId )) {
175- throw new UnsupportedOperationException (
176- "The EPHEMERAL data: " + key + " can only be updated by its owner: "
177- + jdbcRegistryData .getClientId () + " but not: " + clientId );
173+ jdbcRegistryTransactionTemplate .execute (status -> {
174+ if (jdbcRegistryDataOptional .isPresent ()) {
175+ JdbcRegistryDataDTO jdbcRegistryData = jdbcRegistryDataOptional .get ();
176+ if (!dataType .name ().equals (jdbcRegistryData .getDataType ())) {
177+ throw new UnsupportedOperationException ("The data type: " + jdbcRegistryData .getDataType ()
178+ + " of the key: " + key + " cannot be updated" );
178179 }
179- }
180180
181- jdbcRegistryData .setDataValue (value );
182- jdbcRegistryData .setLastUpdateTime (new Date ());
183- jdbcRegistryDataRepository .updateById (jdbcRegistryData );
181+ if (DataType .EPHEMERAL .name ().equals (jdbcRegistryData .getDataType ())) {
182+ if (!jdbcRegistryData .getClientId ().equals (clientId )) {
183+ throw new UnsupportedOperationException (
184+ "The EPHEMERAL data: " + key + " can only be updated by its owner: "
185+ + jdbcRegistryData .getClientId () + " but not: " + clientId );
186+ }
187+ }
184188
185- JdbcRegistryDataChangeEventDTO jdbcRegistryDataChangeEvent = JdbcRegistryDataChangeEventDTO .builder ()
186- .jdbcRegistryData (jdbcRegistryData )
187- .eventType (JdbcRegistryDataChangeEventDTO .EventType .UPDATE )
188- .createTime (new Date ())
189- .build ();
190- jdbcRegistryDataChangeEventRepository .insert (jdbcRegistryDataChangeEvent );
191- } else {
192- JdbcRegistryDataDTO jdbcRegistryDataDTO = JdbcRegistryDataDTO .builder ()
193- .clientId (clientId )
194- .dataKey (key )
195- .dataValue (value )
196- .dataType (dataType .name ())
197- .createTime (new Date ())
198- .lastUpdateTime (new Date ())
199- .build ();
200- jdbcRegistryDataRepository .insert (jdbcRegistryDataDTO );
201- JdbcRegistryDataChangeEventDTO registryDataChangeEvent = JdbcRegistryDataChangeEventDTO .builder ()
202- .jdbcRegistryData (jdbcRegistryDataDTO )
203- .eventType (JdbcRegistryDataChangeEventDTO .EventType .ADD )
204- .createTime (new Date ())
205- .build ();
206- jdbcRegistryDataChangeEventRepository .insert (registryDataChangeEvent );
207- }
189+ jdbcRegistryData .setDataValue (value );
190+ jdbcRegistryData .setLastUpdateTime (new Date ());
191+ jdbcRegistryDataRepository .updateById (jdbcRegistryData );
192+
193+ JdbcRegistryDataChangeEventDTO jdbcRegistryDataChangeEvent = JdbcRegistryDataChangeEventDTO .builder ()
194+ .jdbcRegistryData (jdbcRegistryData )
195+ .eventType (JdbcRegistryDataChangeEventDTO .EventType .UPDATE )
196+ .createTime (new Date ())
197+ .build ();
198+ jdbcRegistryDataChangeEventRepository .insert (jdbcRegistryDataChangeEvent );
199+ } else {
200+ JdbcRegistryDataDTO jdbcRegistryDataDTO = JdbcRegistryDataDTO .builder ()
201+ .clientId (clientId )
202+ .dataKey (key )
203+ .dataValue (value )
204+ .dataType (dataType .name ())
205+ .createTime (new Date ())
206+ .lastUpdateTime (new Date ())
207+ .build ();
208+ jdbcRegistryDataRepository .insert (jdbcRegistryDataDTO );
209+ JdbcRegistryDataChangeEventDTO registryDataChangeEvent = JdbcRegistryDataChangeEventDTO .builder ()
210+ .jdbcRegistryData (jdbcRegistryDataDTO )
211+ .eventType (JdbcRegistryDataChangeEventDTO .EventType .ADD )
212+ .createTime (new Date ())
213+ .build ();
214+ jdbcRegistryDataChangeEventRepository .insert (registryDataChangeEvent );
215+ }
216+ return null ;
217+ });
208218
209219 }
210220
211221 @ Override
212222 public void deleteJdbcRegistryDataByKey (String key ) {
213223 checkNotNull (key );
214- // todo: this is not atomic, need to be improved
215224 Optional <JdbcRegistryDataDTO > jdbcRegistryDataOptional = jdbcRegistryDataRepository .selectByKey (key );
216225 if (!jdbcRegistryDataOptional .isPresent ()) {
217226 return ;
218227 }
219- jdbcRegistryDataRepository .deleteByKey (key );
220- final JdbcRegistryDataChangeEventDTO registryDataChangeEvent = JdbcRegistryDataChangeEventDTO .builder ()
221- .jdbcRegistryData (jdbcRegistryDataOptional .get ())
222- .eventType (JdbcRegistryDataChangeEventDTO .EventType .DELETE )
223- .createTime (new Date ())
224- .build ();
225- jdbcRegistryDataChangeEventRepository .insert (registryDataChangeEvent );
228+ jdbcRegistryTransactionTemplate .execute (status -> {
229+ jdbcRegistryDataRepository .deleteByKey (key );
230+ final JdbcRegistryDataChangeEventDTO registryDataChangeEvent = JdbcRegistryDataChangeEventDTO .builder ()
231+ .jdbcRegistryData (jdbcRegistryDataOptional .get ())
232+ .eventType (JdbcRegistryDataChangeEventDTO .EventType .DELETE )
233+ .createTime (new Date ())
234+ .build ();
235+ jdbcRegistryDataChangeEventRepository .insert (registryDataChangeEvent );
236+ return null ;
237+ });
226238 }
227239
228240 private void doTriggerJdbcRegistryDataAddedListener (List <JdbcRegistryDataDTO > valuesToAdd ) {
0 commit comments