Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use JPA locking mechanism

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces "how to use JPA locking mechanism". In daily operation, I believe many people have doubts about how to use JPA locking mechanism. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts about "how to use JPA locking mechanism"! Next, please follow the editor to study!

There are two kinds of locking mechanisms in JPA, optimistic locking and pessimistic locking.

Optimistic lock:

Optimistic locks are characterized by the belief that data conflicts or update losses are rare. When it happens, throwing an exception and rolling back is enough to solve the problem.

Pessimistic lock:

The logic of pessimistic lock is that conflicts are likely to occur in every data operation, so getting the recorded lock at the beginning and then recording is the first choice to solve the problem.

A brief introduction to the usage of pessimistic lock

Pessimistic locks are usually SQL-level, which is realized by getting the lock first when reading and writing, which is reflected in the SQL statement.

1.1 EntityManager usage return em.createQuery (sql statement) .setLockMode (LockModeType.NONE). GetResultList (); / / the parsing is about: Query query = getSession (). CreateQuery (hql); query.setLockMode (LockModeType.NONE)

EntityManager is a helper class, and what is returned after createQuery is a Query object, and then through the

SetLockMode can set the level of the lock.

The LockModeType type explains that when the isolation level of a LockMode.READ transaction is Repeatable Read or Serializable, it automatically obtains the LockMode.WRITE optimistic lock when it requests to read the database record, automatically obtains the LockMode.OPTIMISTIC optimistic lock when the request inserts or updates the database record, controls the LockMode.PESSIMISTIC_READ and LockMode.PESSIMISTIC_WRITE the same LockMode.PESSIMISTIC_WRITE transaction and obtains the database lock at the beginning of the LockMode.PESSIMISTIC_FORCE_INCREMENT transaction, sets versionLockMode.NONE to cancel any lock at the beginning of the LockMode.PESSIMISTIC_FORCE_INCREMENT transaction For example, all objects after the end of the transaction, or the detailed usage of update () and two optimistic locks of Session

Optimistically lock the main content of this article

Entity class is the key, and optimistic lock is usually controlled by version.

The corresponding table in the database needs to have a field (arbitrary name), and the field type can be set to BigInt.

The business does not control the field, and the control of the field is handled by the system.

Each modification results in an increment of version

When there is an object that obtains the record at the same time and all need to be modified, when the first transaction has been committed, the version field changes, and the later transaction finds that the version version is incorrect, it cannot be committed and an exception is thrown

Entity class (note the @ Version note) @ Entitypublic class User {@ Id @ GeneratedValue private Long id; private String username; private String userdesc; @ Version private Long version; public User () {} public User (String username, String userdesc) {this.username = username; this.userdesc = userdesc;} public Long getId () {return id } public void setId (Long id) {this.id = id;} public String getUsername () {return username;} public void setUsername (String username) {this.username = username;} public String getUserDesc () {return userdesc;} public void setUserDesc (String userdesc) {this.userdesc = userdesc;} public Long getVersion () {return version } public void setVersion (Long version) {this.version = version;}}

In controller, thread is sleeped by sleep to test transaction delivery.

@ RestControllerpublic class UserController {private Logger logger = LoggerFactory.getLogger (getClass ()); @ Autowired UserService userService; @ PostMapping ("/ changeone") @ Transactional public String changeone () {User user = userService.findUser ("gang"); try {logger.info ("modify 1 before:user-- {}-Versdion: {}", user.getUserDesc (), user.getVersion ()); Thread.sleep (25000) User.setUserDesc ("modify 1"); logger.info ("modify 1: user-- {}-- version: {}", user.getUserDesc (), user.getVersion ());} catch (InterruptedException e) {e.printStackTrace ();} catch (Exception e) {logger.info ("eeeeeeeeeeeeee"); e.printStackTrace () } return "true";} @ PostMapping ("/ changetwo") @ Transactional public String changetwo () {User user = userService.findUser ("gang"); try {logger.info ("modify 2 before:user-- {}-- version: {}", user.getUserDesc (), user.getVersion ()); Thread.sleep (30000) User.setUserDesc ("modify 2"); logger.info ("modify 2version: {}", user.getUserDesc (), user.getVersion ());} catch (InterruptedException e) {e.printStackTrace ();} catch (Exception e) {logger.info ("eeeeeeeeeeeeee"); e.printStackTrace () } return "true";} @ PostMapping ("/ changethree") @ Transactional public String changethree () {User user = userService.findUser ("gang"); logger.info ("modify 3 before:user-- {}-- version: {}", user.getUserDesc (), user.getVersion ()); user.setUserDesc ("modify 3") Logger.info ("modify 3: user-- {}-- version: {}", user.getUserDesc (), user.getVersion ()); return "true";} @ PostMapping ("/ newuser") @ Transactional public String newuser () {logger.info ("save user"); User user = new User (); user.setUserDesc ("first creation"); user.setUsername ("gang") UserService.saveUser (user); return "true";}}

And service and repository

@ Servicepublic class UserService {@ Autowired UserRepository userRepository; public User findUser (String username) {return userRepository.findByUsername (username);} public void saveUser (User user) {userRepository.save (user);}} UserRepository public interface UserRepository extends JpaRepository {User findByUsername (String username);} Summary

It is easy to use, version is automatically growing, the only disadvantage is that the exception thrown is not easy to catch, catch method:

@ Resource private UserTransaction rtc; try {rtc.begin (); User user = userService.findUser ("gang"); user .setDesc ("exception catch"); rtc.commit ();} catch (OptimisticLockException e) {throw new OptimisticLockException ();} catch (Exception e) {throw new Exception ();}

Notice the rtc.begin (); and rtc.commit ()

Unlike @ Transaction, this is a manual submission method

At this point, the study on "how to use the JPA locking mechanism" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report