Spring Boot/Java 8/MySQL here.
I have a widgets
table in my MySQL DB that is modeled by a JPA entity like so:
@Entity
@Table(name = "widgets")
@Data
public class Widget {
@Column(name = "widget_property")
private String property;
// all remaining fields here...
}
And which has a matching, typical, repository:
@Repository
public interface WidgetRepository extends CrudRepository<Long,Widget> {
// JPA methods here...
}
And which also has corresponding controller and service classes as well:
@RestController
@RequestMapping("/v1/widgets")
public class WidgetResource {
@Autowired
private WidgetService widgetService;
// API endpoint methods to CRUD widgets using the service...
}
@Service
public class WidgetService {
// widget methods here...
}
Pretty standard stuff. I now need to present my users with a list of all Widgets
and allow a user to "lock" a particular Widget
for editing. The idea/flow I'm thinking here is:
- A user "locks" a widget, perhaps by clicking a button or selecting a drop-down in the UI
- While the widget is "locked" it will not appear as being available to any other users; also, if another user happened to view the screen (list of available widgets) just before the first user locked a particular widget, and this other user just happens to try and lock the same widget, they will not be allowed to do so. In general, if a widget is locked, no other user can lock it.
- A user can only edit a widget they have "locked"
- When a user is done editing it they may "unlock" it which allows it to be listed, re-locked and re-edited by other users. Or, after 12 hrs, a widget automatically unlocks itself (in case the locking user forgot about it and went home)
I know there's probably all sorts of tricks with optimistic locking that can be done here, but I'm wondering if Spring has anything out of the box (perhaps that leverages @Transactional
?) that would help me out here. I'm not opposed to implementing some type of blocking-queue-with-competing-consumers pattern, however I cannot add any infrastructure or deployment complexity, so it would have to be an in-memory, transactional queuing solution.
Any ideas as to how I can implement this using my tech stack, data model and required user flow? Thanks!